【问题标题】:setTimeout keeps running after clearTimeout has been called调用 clearTimeout 后 setTimeout 继续运行
【发布时间】:2015-02-06 20:14:02
【问题描述】:

我正在为一个对象设置动画以在鼠标按下时向 1 个方向移动,而当鼠标 clic 向上时,动画应该停止。

我正在使用 setTimeout,但在我释放 clic 后它会继续移动一段时间。

var stopmov
function tomove(){
    $('.plwid').animate({
        left: '+=1'
    },1);
    stopmov=setTimeout(function(){ tomove(); }, 1);
}

$('.plwid').mouseup(function(){
    clearTimeout(stopmov);
}).mousedown(function(){
    tomove();
});

http://jsfiddle.net/oa9bsqy1/

【问题讨论】:

  • 您需要检查鼠标是否按下,而不是从您的递归 setTimeout 调用中排队数千个回调。
  • 您不需要匿名函数包装器。您可以使用setTimeout(tomove, 1) 和mousedown(tomove)。
  • @MattBurland 为什么会有问题?每个计时器只创建一个新计时器:下一个。所以取消最后一个计时器将停止动画。问题是最后一个计时器并不总是被取消。

标签: javascript jquery jquery-animate settimeout cleartimeout


【解决方案1】:

您最好在文档而不是元素上添加 moueup。

$(document).mouseup(function(){
    clearTimeout(stopmov);
});
$('.plwid').mousedown(function(){
    tomove();
});

另一个问题是您使用的 1 毫秒会产生大量点击,您需要选择一个更合理的数字。

【讨论】:

    【解决方案2】:

    我玩过setTimeout 和setInterval,但我认为最好在jQuery animate 的done 回调中使用递归调用。

    使用$('.plwid').stop(); 也很容易停止。

    请在下方和此处JSFiddle 找到演示。

    function tomove() {
        $('.plwid').animate({
            left: '+=10'
        },
        100, 'linear', tomove);
    }
    
    $(document).mouseup(function () {
        $('.plwid').stop();
    });
    
    $('.plwid').mousedown(function () {
        tomove();
    });
    .plwid {
        position:relative;
        left:10px;
        background:red;
        width:100px;
        height:100px;
        cursor:pointer;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="plwid"></div>

    【讨论】:

      【解决方案3】:
      var mouseIsDown = false;
      
      function tomove(){
        $('.plwid').animate({
          left: '+=1'
        },1);
        if(mouseIsDown) setTimeout(function(){ tomove(); }, 1);
      }
      
      $('.plwid').mousedown(function(){
        mouseIsDown = true;
        tomove();
      });
      $(document).mouseup(function(){
        mouseIsDown = false;
      });
      

      【讨论】:

        【解决方案4】:

        看起来每次 tomove 运行时,它都会再次运行 settimeout,并且 stopmov 变量将只有最近的 ...

        所以,就拿走

        stopmov=setTimeout(function(){ tomove(); }, 1);
        

        出了第一个函数。鼠标悬停时调用 settimeout。

        var stopmov
        function tomove(){
            $('.plwid').animate({
                left: '+=1'
        },1);
        }
        $('.plwid').mouseup(function(){
            clearTimeout(stopmov);
        }).mousedown(function(){
            stopmov=setTimeout(function(){ tomove(); }, 1);
        });
        

        【讨论】:

        • 但是不会有任何动画。每次点击只需移动一个像素。
        • 哦,对了……我把 setTimeout 和 setInterval 搞混了。您是否尝试过 setInterval?
        猜你喜欢
        • 2017-07-29
        • 1970-01-01
        • 2017-06-04
        • 2021-12-10
        • 2021-09-23
        • 1970-01-01
        • 2021-03-01
        • 1970-01-01
        相关资源
        最近更新 更多