为什么这个 setTimeout() 调用可以在控制台中工作,但不能作为 Greasemonkey 脚本工作?

发布于 2024-12-03 20:06:43 字数 1008 浏览 1 评论 0原文

当我在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

森林很绿却致人迷途 2024-12-10 20:06:43

因为当在 setTimeout 触发时对字符串进行求值以执行该函数时,循环已经运行完毕,并且 i 位于循环的最后一个值。

要冻结每次调用 setTimeout 的 i 值,您需要在函数闭包中捕获它,如下所示:

function test2() {
  for( var i = 0; i < 100; i+= 10 ) {
    setTimeout(function(val) {
        return(function() {test(val);});
    } (i), 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:

function test2() {
  for( var i = 0; i < 100; i+= 10 ) {
    setTimeout(function(val) {
        return(function() {test(val);});
    } (i), i);
  }
}

This also has the advantage of getting rid of the eval in the setTimeout parameter.

盛装女皇 2024-12-10 20:06:43

您必须将 i 的值复制到本地范围的变量中:

function test2() {
  for( var i = 0; i < 100; i+= 10 ) {
    (function(i){
        setTimeout('test('+i+');', i);
    })(i);
  }
}

旁注:您应该将匿名函数传递给 setTimeout 而不是向其传递一个字符串(将被评估)。这样要快得多:

function test2() {
    for( var i = 0; i < 100; i+= 10 ) {
        (function(i){
            setTimeout(function(){
                test(i);
            }, i);
        })(i);
    }
}

You have to duplicate the value of i into a locally scoped variable:

function test2() {
  for( var i = 0; i < 100; i+= 10 ) {
    (function(i){
        setTimeout('test('+i+');', i);
    })(i);
  }
}

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:

function test2() {
    for( var i = 0; i < 100; i+= 10 ) {
        (function(i){
            setTimeout(function(){
                test(i);
            }, i);
        })(i);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文