I have a grid of images, which users can mouseover to preview. I am able to add a listener to each one in a loop. I would only like to trigger my logic if the user is over the item for at least 1.5 seconds. I can't determine why my mouseleave event which attempts to clearTimeout of the timer, is not actually clearing it.
I have added comments in the code to also clarify:
(function () {
var nodeList = document.querySelectorAll('div.MyDiv > img') || undefined;
if (nodeList) {
nodeList.forEach(function (_el, idx) {
_el.addEventListener("mouseenter", function (e) {
var _imgsrcga = e.srcElement.src;
var timer = setTimeout(function() {
console.log('This ran'); // this is OK after 1.5 seconds, but it ALWAYS runs after 1.5 seconds
}, 1500)
}, false);
// not clearing the timer....
_el.addEventListener("mouseleave", function(e) {
console.log('cleared')
clearTimeout(timer) // my timer never clears with a mouseleave event
})
})
}
})();
So: my console.log('this ran') does in fact delay 1.5 seconds, but I can never get rid of my timer if they mouseleave in < 1.5 seconds.
Thanks
Declare the timer outside the function in order to be accesible from other functions.
(function () {
var timer;
var nodeList = document.querySelectorAll('div.MyDiv > img') || undefined;
if (nodeList) {
nodeList.forEach(function (_el, idx) {
_el.addEventListener("mouseenter", function (e) {
var _imgsrcga = e.srcElement.src;
timer = setTimeout(function() {
console.log('This ran');
}, 1500)
}, false);
_el.addEventListener("mouseleave", function(e) {
console.log('cleared')
clearTimeout(timer)
})
})
}
})();
<div class="MyDiv">
<img src="http://placekitten.com/g/200/300">
</div>
I include the way i would write this piece of code. In my opinion, your code could be structured differently, for the sake of readability & understanding. I've removed some unnecessary lines too, and used ES6 syntax.
(function () {
let timer;
let nodeList = document.querySelectorAll('div.MyDiv > img');
const mouseOver = e=> {
let _imgsrcga = e.target.src;
timer = setTimeout( ()=> console.log('This ran'), 1500)
};
const mouseOut = e=> {
console.log('cleared')
clearTimeout(timer)
};
nodeList.forEach( _el=>{
_el.addEventListener("mouseover", mouseOver , false);
_el.addEventListener("mouseout", mouseOut);
});
})();
<div class="MyDiv">
<img src="http://placekitten.com/g/200/300">
</div>
Notes :
mouseover
and mouseout
events instead