为什么这个setTimeout()调用在控制台中工作但不是作为greasemonkey脚本? [英] why does this setTimeout() call work in the console but not as a greasemonkey script?
问题描述
当我在greasemonkey脚本中的for()循环中使用setTimeout()时,它似乎根本不起作用。但是,如果我在Firebug控制台中运行它,完全相同的代码工作正常。这是代码:
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);
如果我用如下所示的显式调用替换for()循环,那么它可以正常工作。 / p>
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);
有什么区别?有什么方法可以让for循环生成的setTimeouts在greasemonkey中工作吗?
What's the difference? Is there any way I can get the for loop generated setTimeouts to work in greasemonkey?
推荐答案
因为当setTimeout触发以执行函数时,字符串被唤醒,循环运行它的过程并且 i
位于循环的最后一个值。
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.
冻结 i
对于每次调用setTimeout,你需要在函数闭包中捕获它,如下所示:
To freeze the value of i
for each call to setTimeout, you need to capture it in a function closure like this:
function test2() {
for( var i = 0; i < 100; i+= 10 ) {
setTimeout(function(val) {
return(function() {test(val);});
} (i), i);
}
}
这也有摆脱eval的优势在setTimeout参数中。
This also has the advantage of getting rid of the eval in the setTimeout parameter.
这篇关于为什么这个setTimeout()调用在控制台中工作但不是作为greasemonkey脚本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!