如何在嵌套悬停事件中正确销毁 javascript 计时器对象?

How do I properly destroy a javascript timer object in a nested hover event?

我很难从悬停事件中正确清除计时器功能。我有两个 div。他们是兄弟姐妹,下一个兄弟姐妹应该显示在另一个的悬停上。我无法确定我在哪里搞砸了,但我发现每次我将鼠标悬停在主要项目上时,它都会创建一个带有 setTimeout 的全新计时器。所以第一次迭代工作正常,第二次悬停将触发两次,依此类推。

    .main-item {
      width: 300px;
      height: 100px;
      background: #000;
    }

    .sub-item {
      display: none;
      width:450px;
      height: 75px;
      background: red;

      &.open {
        display: block;
      }

    }



    <div>
      <div class="main-item">
      </div>
      <div class="sub-item"></div>
    </div>

    var timer;

    $('.main-item').hover(function() {
      var $this = $(this);
      var $sub = $this.next();

      $sub.addClass('open');

}, function() {
  var $this = $(this);
  var $sub = $this.next();

  $sub.hover(function() {
    var $this = $(this);
    clearTimeout($this.data('timerId'));
    timer = null;

    console.log(timer);

  }, function() {
    var $this = $(this);
    timer = setTimeout(function() {
      $this.removeClass('open');
      alert('this triggered');
    }, 2000);
    $this.data('timerId', timer);
  });

});

问题不在于计时器,而在于绑定事件处理程序。 每次鼠标离开 .main-item 时,您都会将悬停处理程序绑定到 .sub-item。您需要删除以前的处理程序,或者设置一个布尔值来记住您已经绑定了悬停处理程序,或者使用 jquery 函数 onemouseentermouseoff 事件,有很多方法可以解决这个问题。

使用 $sub.off() 删除以前的处理程序。

https://jsfiddle.net/p2wtonac/2/

使用布尔值绑定一次。

https://jsfiddle.net/p2wtonac/3/