Добавление eventListeners в цикле (mouseenter), но срабатывание только через 1500 мс - проблема с clearTimeout - PullRequest
0 голосов
/ 12 января 2019

У меня есть сетка изображений, которую пользователи могут при наведении мыши для предварительного просмотра. Я могу добавить слушателя для каждого в цикле. Я хотел бы активировать свою логику только в том случае, если пользователь находится над элементом не менее 1,5 секунд. Я не могу определить, почему мое событие mouseleave, которое пытается очистить время таймера, на самом деле не очищает его.

Я добавил комментарии в коде, чтобы также уточнить:

(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
      })
    })
  }
})();

Итак: мой console.log ('this run') на самом деле задерживает 1,5 секунды, но я никогда не смогу избавиться от своего таймера, если он оставит мышь менее чем за 1,5 секунды.

Спасибо

Ответы [ 2 ]

0 голосов
/ 12 января 2019

Объявите таймер вне функции, чтобы быть доступными для других функций.

(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>

Я включил способ, которым я написал бы этот кусок кода. На мой взгляд, ваш код может быть структурирован по-другому, для удобства чтения и понимания. Я также удалил некоторые ненужные строки и использовал синтаксис ES6.

(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>

Примечания:

  • используйте mouseover и mouseout события вместо
  • не используйте e.srcElement, используйте e.target (стандартный)
  • не нужно проверять nodeList после querySelectionAll (в худшем случае у вас будет пустой список, а forEach ничего не будет делать)
  • не объявлять встроенные обработчики событий (лучшая производительность)
0 голосов
/ 12 января 2019

переменная «таймер» не отображается в функции очистки. Это приватная переменная для функции события mouseenter.

...