Advertisements
I have a function A to select the .current
element and do something to it. Then, (re)move the .current
class name to another element and do the same thing to it.
function funA () {
let state = [];
let currentRow = document.querySelector(".current");
//...
evaluateThings(function () {
currentRow.classList.remove("current");
currentRow.nextSibling.classList.add("current");
funcA();
});
}
function evaluateThings(callback) {
//...
callback()
}
funcA()
The issue is, funcA
remembers the previous selector and makes changes to both, the new .current
and the last one
>Solution :
funcA
adds a keydown listener to the document. When you recursively call funcA
, you aren’t removing the previous listener, so on the next event, both run, and both elements get changed – and the cycle continues.
Remove the prior listener when doing the recursive call.
function funcA() {
const currentRow = document.querySelector(".current");
const handler = (e) => {
if (e.key === 'Enter') {
currentRow.nextElementSibling.classList.add("current");
currentRow.classList.remove("current");
document.removeEventListener("keydown", handler);
evaluateThings(funcA);
} else {
currentRow.innerHTML += e.key
}
};
document.addEventListener("keydown", handler);
}
function evaluateThings(callback) {
//...
callback()
}
funcA()
<div class="row current">a</div>
<div class="row">b</div>
<div class="row">c</div>
<div class="row">d</div>
<div class="row">e</div>
<div class="row"></div>
Or keep the listener attached, but reassign the variable that points to the element.
let currentRow = document.querySelector(".current");
function funcA() {
document.addEventListener("keydown", (e) => {
if (e.key === 'Enter') {
currentRow.nextElementSibling.classList.add("current");
currentRow.classList.remove("current");
evaluateThings(() => currentRow = document.querySelector(".current"));
} else {
currentRow.innerHTML += e.key;
}
});
}
function evaluateThings(callback) {
//...
callback()
}
funcA()
<div class="row current">a</div>
<div class="row">b</div>
<div class="row">c</div>
<div class="row">d</div>
<div class="row">e</div>
<div class="row"></div>