I am trying to build a drag and drop system, which highlights available dropzones when dragging a dragitem over them. I do this by adding a class to a dropzone, when a suitable drag item hovers over it. However, when the drag item leaves ("dragleave" event), sometimes the class does not get removed and the highlight says. What could be a possible reason for this behavior and how do I fix it?
Example of the bug:
Code excerpt:
// drag events
element.addEventListener("dragenter", (event) => {
event.stopPropagation();
event.preventDefault();
checkBacktrack(event.target);
});
element.addEventListener("dragleave", (event) => {
event.stopPropagation();
event.preventDefault();
if (event.target === nodeStack.at(-1)) {
popNodeStack();
}
});
// Node stack functions (nodeStack = stack of nodes to keep track):
const checkBacktrack = (element) => {
for (let i = nodeStack.length - 1; i >= 0; i--) {
const topNode = nodeStack.at(-1);
if (topNode === element) {
return true;
} else if (topNode.contains(element)) {
pushNodeStack(element);
return true;
} else {
popNodeStack();
}
}
pushNodeStack(element);
return false;
};
const popNodeStack = () => {
const removedNode = nodeStack.pop();
tryPopHighlight(removedNode);
};
const pushNodeStack = (element) => {
nodeStack.push(element);
tryPushHighlight(element);
};
//Highlight functions (highlightStack = stack of elements to highlight):
const tryPushHighlight = (element) => {
if (_isValidDropzone(element)) {
pushHighlight(element);
}
};
const tryPopHighlight = (element) => {
if (highlightStack.at(-1) === element) {
popHighlight();
}
};
const pushHighlight = (element) => {
element.classList.add("drag-under-item");
const currentHighlight = highlightStack.at(-1);
if (currentHighlight) {
currentHighlight.classList.remove("drag-under-item");
}
highlightStack.push(element);
};
const popHighlight = () => {
setTimeout(() => {
const removedHighlight = highlightStack.pop();
if (removedHighlight)
removedHighlight.classList.remove("drag-under-item");
const newHighlight = highlightStack.at(-1);
if (newHighlight) newHighlight.classList.add("drag-under-item");
});
};
Literally 1 minute after posting this I found the issue. I moved nodeStack and highlightStack out of the function body into a static context, now everything is working like magic...