JavaScript:如何通过点击按钮退出循环

3

我进行了一些搜索,甚至不确定我想要做的是否是良好的JavaScript实践。 如果单击停止按钮,我希望退出while循环。

$( "#go" ).click(function() {
  var gotime = 1;
  while (gotime < 100) {
    for(i = 0; i < 2; i++){
      var divName = "floatName" + i;
      console.log(divName);
      $( "#" + divName ).animate({
        left: Math.random()*500 + "px",
        top: Math.random()*500 + "px"
      }, 500, function() {
        // Animation complete.
      });
    };

    gotime += 1;

    $( "stop" ).click(function() {
      gotime = 101;
    });
    };
});

这个并不起作用。我最初有一个无限循环(没有递增gotime)。

http://jsfiddle.net/cvoxe465/

3个回答

3

实际上,如果你等待一段时间,它就会停止。问题在于你经常执行动画,$.animate必须排队。有一个$.stop的方法可以让你停止当前正在运行的动画。示例

$( "#stop" ).click(function() {
  gotime = 101;
  $('#floatName0, #floatName1').stop(true, true);
});

编辑:

请注意,在您提供的代码中存在错误。您需要使用$("#stop")而不是$("stop")


请同时提到 $(stop) 应该是 $(#stop),这就是为什么点击按钮事件没有触发,最终我们不得不等待循环完成的原因。 - Sudhansu Choudhary

1

animate 不会阻塞循环。动画被堆叠起来,然后执行,但是循环会更早结束。这里有一个可以工作的示例:

var loopAllowed = false;
$('#go').click(function(){
    loopAllowed = true;
    var max = 2;
    var loop = function(){
        for(var i = 0; i < max; i++){
            var divName = "floatName" + i;
            $( "#" + divName ).animate({
                left: Math.random()*500 + "px",
                top: Math.random()*500 + "px"
            }, 500, i === max - 1 && loopAllowed ? loop : undefined);
        }
    };
    loop();
});

$('#stop').click(function(){
    loopAllowed = false;    
});

JSFiddle。在动画结束后,我们手动调用loop函数作为回调函数。如果loopAllowed为false(例如通过单击#stop设置为false),则它不会作为回调函数传递,循环停止。


我喜欢这个解决方案,因为我计划动画化更多的名称,而这个解决方案不需要更多的floatNameX调用。 - Doug Smith
你能简要解释一下i == max - 1 && loopAllowed ? loop : undefined的含义吗?我知道i == max - 1 && loopAllowed检查了一个条件,但是我不明白?loop : undefined。而且,我也没看到这些部分与jquery文档http://api.jquery.com/animate/有什么关系。这是队列选项的一部分吗? - Doug Smith
@DougSmith 这是三元运算符。它本质上是if的简写 - 如果条件为true,则将loop作为回调函数传递,如果条件为false,则将未定义的回调函数(将结束循环)传递。回调在动画完成后调用 - 这就是为什么我们可以像这样循环(在动画之后,loop会再次被调用)。默认情况下,queue选项为true(动画默认放置在队列中,然后按顺序执行),但我的代码不涉及该选项。 - Oliver

1
你可以使用 setInterval
Js:
var interval;
$("#go").click(function () {
    var gotime = 1;
    interval = setInterval(function () {
        for (i = 0; i < 2; i++) {
            var divName = "floatName" + i;
            console.log(divName);
            $("#" + divName).css({
                left: Math.random() * 500 + "px",
                top: Math.random() * 500 + "px"
            });
        };
        gotime += 1;
        if (gotime > 100) {
            clearInterval(interval);
        }
    }, 500)
});
$("#stop").on('click', function () {
    clearInterval(interval);
});

CSS:

#randomFloat {
    color: red;
}
#floatName1, #floatName0 {
    transition : 0.5s left, 0.5s top;
}

小提琴


谢谢,那很有道理。我猜它很快地通过for循环。我以为它每500毫秒循环一次,这是动画时间。 - Doug Smith
@DougSmith:嗨,我在这里发布答案的原因是因为你要求好的JavaScript实践。如果您将变量gotime = 101,当用户单击停止时,您将无法恢复动画。如果您删除它,则即使停止动画,while循环也将运行100次。现在再次阅读答案,看看哪个更好。 :) - Ajay Narain Mathur
@AJ:是的,我也可以把这个转换放到#randomFloat里面,因为我看到它被继承了。谢谢! - Doug Smith
@AJ 我回来调试一下。这个策略很好,但是如果用户先点击#go,然后再次点击#go,动画将不会停止。我分叉了Fiddle,尝试使用gotime来切换clearInterval,但似乎没有起作用。 - Doug Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接