所以,我创建了一个容器div,在div中我有一个脚本动态创建113个div,类名为'fragment'。现在,一切都井然有序,我专门制作了113个div非常小,大约5X5像素。然后我把它们放在容器中,这样他们拼出一个标题。所有div都在一个名为 divs 的数组中。所以div是一个包含113个元素的数组。
现在这里的事情令人困惑,我想让这些div隐藏在浏览器的隐形区域后面,我通过给出'片段'的绝对定位来实现这一点,并将它们设置成隐藏例如:divs[45].style.left = -600';
,之后,我创建了一个运行 for-loop 的脚本,并且在for循环内部我希望每个小元素在延迟后返回到它的位置。但是,我必须使用闭包,因为在for循环中插入SetTimeout()
是很奇怪的。
for (i = 0; i < divs.length; i++)
{
(function(j)
{
setTimeout(function ()
{
divs[j].style.left = divs[j].offsetLeft + 550;
}, Math.floor(Math.random() * 1000));
})(i); //Pass current value into self-executing anonymous function
}
我无法绕过上面的代码。我认为写Math.floor(Math.random() * 1000)
的区域是以ms为单位指定延迟。但是,如果我输入1000,它将同时移动所有113个元素。我不明白这一点,它不应该在移动到阵列中的下一个元素之前等待1秒钟吗?顺便说一句,代码工作正常,最终发生的是元素随机移动给标题一个非常酷的效果。对我的封闭让人感到困惑,对我来说这似乎是一种奇怪的行为。
有人会如此善意地解释为什么会发生这种情况,如果我拿出Math.floor(Math.random() * 1000)
,为什么所有元素都会立即进入,而不是简单地让每一个元素每隔一秒移动一次...... *
修改
我的问题不是关于闭包,而是关于为什么取出Math.floor(Math.random() * 1000)
并用'1000'代替它,导致所有元素一次移入,而不是一个接一个地间隔1000ms
答案 0 :(得分:1)
所有的setTimeout都在(几乎)同时被实例化,并且因为它们都有1秒的延迟,所以它们都在(几乎)同时启动。
答案 1 :(得分:0)
如果要按顺序添加元素,则需要递归执行。如果您使用for
循环,那么您将同时&#34;同时&#34;安排一堆计时器。他们都会在同一时间开始倒计时,他们都会尽快完成,而不会彼此关注。
以下是如何按顺序安排计时器的示例:
var things = [1, 2, 3];
(function next(array) {
setTimeout(function () {
var item = array[0],
remaining = array.slice(1);
console.log(item);
if (remaining.length > 0) {
next(remaining);
}
}, 1000);
}(things));
如果您正在进行大量异步工作,或者您希望处理与同步任务类似的异步任务,请尝试Async。它提供了一些很好的循环机制:
async.eachSeries(things, function (thing, callback) {
setTimeout(function () {
console.log(thing);
callback();
}, 1000);
}, function () {
console.log('all done');
});
答案 2 :(得分:0)
好的,所以你想要这样的东西...... http://jsfiddle.net/92xx7u21/
Javascript:
var oDivs = document.getElementsByTagName('div');
window.doit = function(iLength, iCounter){
setTimeout(function () {
$(oDivs[iCounter]).width(($(oDivs[iCounter]).width() - 10) + "px");
iCounter++;
if (iCounter<iLength) {
doit(iLength, iCounter);
} else {
alert('done');
}
}, 1000);
};
doit(oDivs.length, 0);
基本上这是一个自我调用函数,你用底线开始一次,然后它会调用自己,直到它达到元素的长度..它可以被清理一点,但试图保持简单..你需要再次添加随机时间,因为我每循环保持1秒钟。
由于我没有你的任何其他代码,我用jQuery做了这个,使它成为一个简单的例子,在这种情况下也只是调整宽度。
答案 3 :(得分:-1)
鉴于以前的答案,我很确定你理解;这只是对代码的修改,可以做你想做的事情,甚至可以帮助你进一步理解:
for (i = 0; i < divs.length; i++)
{
(function(j)
{
setTimeout(function ()
{
divs[j].style.left = divs[j].offsetLeft + 550;
}, j * 1000); // simply multiply j by 1000
})(i); //Pass current value into self-executing anonymous function
}
编辑(解释):setTimout接受以毫秒为单位的延迟(1/1000秒),j
在0
和divs.length-1
之间。通过将此值乘以在操作之间延迟的毫秒数,您最终会给它从上一次执行代码开始等待每次执行的总毫秒数。