为什么这个 setTimeout() 调用可以在控制台中工作,但不能作为 Greasemonkey 脚本工作?
当我在 Greasemonkey 脚本的 for() 循环中使用 setTimeout() 时,它似乎根本不起作用。但是,如果我在 Firebug 控制台中运行完全相同的代码,则它可以正常工作。代码如下:
// ==UserScript==
// @name setTimeout test
// @include *
// @run-at document-end
// ==/UserScript=
function test(delaytime) {
alert("test called with "+delaytime);
}
function test2() {
for( var i = 0; i < 100; i+= 10 ) {
setTimeout('test('+i+');', i);
}
}
setTimeout(test2,10);
如果我用如下所示的显式调用替换 for() 循环,那么它就可以正常工作。
setTimeout(function() { test( 0); }, 0);
setTimeout(function() { test(10); }, 10);
setTimeout(function() { test(20); }, 20);
setTimeout(function() { test(30); }, 30);
setTimeout(function() { test(40); }, 40);
setTimeout(function() { test(50); }, 50);
setTimeout(function() { test(60); }, 60);
setTimeout(function() { test(70); }, 70);
setTimeout(function() { test(80); }, 80);
setTimeout(function() { test(90); }, 90);
有什么区别?有什么办法可以让for循环生成的setTimeouts在greasemonkey中工作吗?
When I use a setTimeout() in a for() loop in a greasemonkey script, it doesn't appear to work at all. However, the exact same code works fine if I run it in the Firebug console. Here's the code:
// ==UserScript==
// @name setTimeout test
// @include *
// @run-at document-end
// ==/UserScript=
function test(delaytime) {
alert("test called with "+delaytime);
}
function test2() {
for( var i = 0; i < 100; i+= 10 ) {
setTimeout('test('+i+');', i);
}
}
setTimeout(test2,10);
If I replace the for() loop with explicit calls like the following, then it works fine.
setTimeout(function() { test( 0); }, 0);
setTimeout(function() { test(10); }, 10);
setTimeout(function() { test(20); }, 20);
setTimeout(function() { test(30); }, 30);
setTimeout(function() { test(40); }, 40);
setTimeout(function() { test(50); }, 50);
setTimeout(function() { test(60); }, 60);
setTimeout(function() { test(70); }, 70);
setTimeout(function() { test(80); }, 80);
setTimeout(function() { test(90); }, 90);
What's the difference? Is there any way I can get the for loop generated setTimeouts to work in greasemonkey?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
因为当在 setTimeout 触发时对字符串进行求值以执行该函数时,循环已经运行完毕,并且
i
位于循环的最后一个值。要冻结每次调用 setTimeout 的
i
值,您需要在函数闭包中捕获它,如下所示:这还有一个优点,即可以摆脱 setTimeout 参数中的 eval。
Because when the string is evaled at the time the setTimeout fires in order to execute the function, the loop has run it's course and
i
is sitting at the last value of the loop.To freeze the value of
i
for each call to setTimeout, you need to capture it in a function closure like this:This also has the advantage of getting rid of the eval in the setTimeout parameter.
您必须将
i
的值复制到本地范围的变量中:旁注:您应该将匿名函数传递给
setTimeout
而不是向其传递一个字符串(将被评估)。这样要快得多:You have to duplicate the value of
i
into a locally scoped variable:On a side note: You should pass an anonymous function to
setTimeout
instead of passing it a string (which will be eval'ed). It's much faster this way: