里面所有的JavaScript的一个定时器,用于循环发生一次(All the setTimeouts

2019-07-04 18:29发布

这个函数应该向下从页面下方215个像素的顶部在20ms的滚动,越来越延迟,从而使第一window.scrollTo事件发生在10毫秒,接下来,等等。
最后一行应以2150毫秒所以在所有需要约2秒延迟。
相反,它会立即向下滚动215个像素的一次。

function scrollDown() {
  var yFinal=216, delay=0;
  for (y=0; y<yFinal; y++) {
    delay = delay+10
    setTimeout(function() {
      window.scrollTo(100,y);
    },delay);
  }
}

悲伤的脸。 为什么?

[编辑:感谢您的帮助! 我用它来写这个最终的解决方案,它是更复杂一点,我在这里提供它的任何人都懵了。 它在第一,然后缓慢滚动快。 正是我想要的。 使用的setTimeout insteat的setInterval的,它可以让你的速度曲线进行更多的控制,所以你可以很容易使其成倍减缓]

function showCategory(categoryId)
{
  var yInitial=document.body.scrollTop,
      yFinal=216,
      delay=0;

  if (yInitial<yFinal)
  {
    yInitial=(yFinal-yInitial)/1.3+yInitial;
    window.scrollTo(100, yInitial);

    for (var yCurrent = yInitial; yCurrent < yFinal; yCurrent+=2)
    {
      delay += 30;
      (function(position)
      {
        setTimeout(function()
        {
          window.scrollTo(100, position);
        }, delay);
      })(yCurrent);
    }
  }
}

Answer 1:

超时一切发生一次,他们碰巧与你所期望的时机。 然而,他们都试图滚动到由同一所代表的位置y变量,所以他们都使用任何值y具有循环结束时。

此错误的通常的解决办法是引入一个封闭:

function scrollDown() {
    var yFinal = 216,
        delay = 0;

    for (var y = 0; y < yFinal; y++) {
        delay += 10;
        (function(position) {
            setTimeout(function() {
                window.scrollTo(100, position);
            }, delay);
        })(y);
    }
}​

(另请注意,您y变量是全球性的:你应该把它声明var ,使其地方。)



Answer 2:

你必须包装setTimeout在一个匿名函数传递y按价值计算,而不是按引用:

(function(y) {
    setTimeout(function() {
        window.scrollTo(100,y);
    }, delay);
})(y);


文章来源: All the setTimeouts inside javascript for loop happen at once