在循环内设置超时

时间:2017-06-01 18:49:47

标签: javascript jquery

在for循环中设置超时的最佳方法是什么?我有一个方块,点击后,预期的结果是它每500毫秒下降1px。我试图通过将top属性的CSS值设置为i并以500毫秒的超时包装来实现此目的。

正在发生的事情是,在直接向下发射前,它会“挂起”在前几个像素上。

到目前为止我的内容如下:

$("#rect").click(function() {
 	for (i = 0; i < 200; i++) {
    	(function(i){
      	setTimeout(function() {
        $("#rect").css("top", i) 
        }, 500);
      })(i); 
  } 	
});

$("#reset").click(function() {
  	$("#rect").css("top", "0"); 
});
#rect {
  position: absolute;
  top: 0;
  width: 200px;
  height: 50px;
  background-color: #333;
}

#rect:hover {
  cursor: pointer;
}

#reset {
  float: right;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id="rect"></div>

<button id="reset">reset</button>

在循环内的超时中说明i的顶级属性值的结果不起作用?

4 个答案:

答案 0 :(得分:1)

您的计时功能错误,将其更改为500 * i;如果你想让它移动每一次迭代。

目前你所有的setTimeOuts都会以500毫秒的速度发射,这就是它跳转的原因

$("#rect").click(function() {
    for (let i = 0; i < 200; i++) {
        setTimeout(function() {
        $("#rect").css("top", i); 
        }, 500*i); 
  }     
});

$("#reset").click(function() {
    $("#rect").css("top", "0"); 
});

但是您可以使用其他答案中提到的许多其他解决方案。动画,向上滑动更加强大。

答案 1 :(得分:0)

你setTimeout是一个匿名函数,所以循环调用函数并进入下一次迭代,几乎一次设置超时。

此外,您可能希望使用setInterval来执行此操作。它多次重复回调。

https://www.w3schools.com/jsref/met_win_setinterval.asp

答案 2 :(得分:0)

我没有检查你的代码,但如果你需要移动一个矩形并且你已经使用了jQuery,你可以使用jQuery滑动效果 https://api.jquery.com/category/effects/sliding/

一个例子:

$( "#book" ).slideUp( "slow", function() {
    // Animation complete.
  });

有时很难创建这样的简单效果,因为它与浏览器如何在绘画上呈现非常快速的变化有关

答案 3 :(得分:0)

看起来您正在创建200个超时,这些超时都会同时运行,每个超时都会将元素向下移动一个像素,从而显示出它击落的外观。

你想要的更接近这一点。设置一个间隔来运行你的函数,每500毫秒移动一次框:

setInterval(moveBox, 500);
var boxMovedTimes = 0;

function moveBox() {
  $('#rect').css('top', boxMovedTimes + "px");
  boxMovedTimes += 1;
  console.log('moved ' + boxMovedTimes)
}