【问题标题】:SetTimeout on vanilla JS on []forEach.call not working in sequences[]forEach.call 上的香草 JS 上的 SetTimeout 无法按顺序工作
【发布时间】:2016-09-24 23:12:10
【问题描述】:

我正在尝试为序列中的所有 LI 设置动画,但代码会同时为所有 LI 设置动画。

我在任何地方都找不到有用的回复,我知道如何在 Jquery 中执行此操作,但这里没有加起来。

我尝试将超时添加到事件处理程序和被调用函数,这两种方法都不起作用。

这是函数

function changeLi() {
  setTimeout(function() {
    [].forEach.call(li, function(li) {
      li.style.transform = "translateX(200px)";
    }, 900);
  });
}

codepen 链接:

http://codepen.io/damianocel/pen/PzYXmv

我尝试将 stopPropagation/preventDefault 添加到调用中,但这也无济于事。

【问题讨论】:

  • 你的大括号匹配搞砸了。请修复它并正确缩进您的代码。
  • 您似乎对how setTimeout works 有一个根本性的误解。还有stopPropagationpreventDefault,它们都只适用于事件。
  • 您使用 setTimeout 就像它像 sleep 一样工作。有关解决方案,请参见 [此处](Python while 循环转换为 Javascript)。
  • setTimeout() 只会控制动画何时开始,设置style.transform 时。动画本身将独立于超时运行和完成。 – Is there a callback on completion of a CSS3 animation?
  • @hamms 我尝试了 stopPropagation,因为整个 UL 都是动画的。下一个问题是“this”范围,Jquery 负责处理,但在这里,显然有些地方不对。

标签: javascript


【解决方案1】:

您的代码存在几个问题。首先,900 不是您的setTimeout 的参数,而是forEach.call 的参数。这似乎只是一个错误。

其次,即使上述问题已修复,您的代码也会在未来简单地设置一个 900 毫秒的超时时间,然后遍历列表中的所有 li 并立即对其进行转换

时间>。我相信您真正想要做的是遍历所有项目并定义将来运行的超时,其中每个项目都从前一个项目运行一定时间。由于forEach 提供了一个索引,因此您可以使用静态毫秒计数并将其乘以您列表的当前索引,以便从现在进一步进行动画处理。

我相信您实际上正在寻找这样的东西,它会循环您的 li 列表,并设置一个转换,使其在每个项目上发生 100 毫秒的前一个:

function changeLi() {
  [].forEach.call(li, function(li, i) {
    setTimeout(function() {
      li.style.transform = "translateX(200px)";
    }, 100 * i);
  });
}

【讨论】:

  • 这有点工作,但它会在 2 次迭代后停止。它正确地为第一个项目设置动画,然后立即为整个 UL 设置动画。有没有办法将 bind() 用于“this”上下文?
  • 澄清一下,你是对的,我确实试图让转换在给定的时间范围后按顺序发生。
  • 完美,刚刚看到你的编辑,现在完美无缺:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多