I've done my best to find this question already being asking but came up empty handed so I hope this isn't a duplicate.
In short, I've written a factory function to help me with some drag & drop functionality in a project I'm working on, but am seeing different behavior depending on how I write some of the methods inside of it.
Here's the code in total:
const draggables = document.querySelectorAll(draggablesSelectors);
const containers = document.querySelectorAll(containersSelectors);
draggables.forEach(draggableEl => {
draggableEl.addEventListener("dragstart", dragStart, false);
draggableEl.addEventListener("dragend", dragEnd, false);
});
function dragStart() {
console.log("drag start");
}
function dragEnd() {
console.log("drag end");
}
const returnDraggables = () => {
return draggables;
}
const returnContainers = () => {
return containers;
}
return {returnDraggables, returnContainers};
}
const draggableEls = Draggable(".ship", ".gameboard");
I know using arrow functions changes the lexical scope of this
, but what I could use some help understanding is why I'll see "drag start" and "drag end" in the console when I write the dragStart
and dragEnd
functions the way they are above, but when I write them as arrow functions they don't do anything.
Thanks very much!
UPDATE: Thanks to @kikon for helping me realize I had the function declarations after the forEach loop. Once I moved things into the correct order (shown below) everything is working great.
const draggables = document.querySelectorAll(draggablesSelectors);
const containers = document.querySelectorAll(containersSelectors);
// Draggables Functions
const dragStart = () => {
console.log("drag start");
}
const dragEnd = () => {
console.log("drag end");
}
const dragDrop = () => {
console.log("drop");
}
// Container Functions
const dragOver = () => {
console.log("drag over");
}
const dragEnter = () => {
console.log("drag enter");
}
const dragLeave = () => {
console.log("drag leave");
}
const returnDraggables = () => {
return draggables;
}
const returnContainers = () => {
return containers;
}
draggables.forEach(draggableEl => {
draggableEl.addEventListener("dragstart", dragStart, false);
draggableEl.addEventListener("dragend", dragEnd, false);
draggableEl.addEventListener("drop", dragDrop, false);
});
containers.forEach(containerEl => {
containerEl.addEventListener("dragover", dragOver, false);
containerEl.addEventListener("dragenter", dragEnter, false);
containerEl.addEventListener("dragleave", dragLeave, false);
});
return {returnDraggables, returnContainers};
}
const draggableEls = Draggable(".ship", ".gameboard");
console.log(draggableEls.returnDraggables());
export default Draggable;```
I think the cause might be the fact that you declare/define the handlers dragStart
and dragEnd
after they are used in the forEach
loop.
That works with functions, as they are hoisted, but not with var
s or const
s. Still, if you used const
, as for the other arrow functions, you
should have got a ReferenceError
.