Javascript:函数已定义,但错误说..找不到函数! (奇怪)

时间:2011-05-07 07:48:01

标签: javascript javascript-events asynchronous greasemonkey

这是我的代码:

function mark()
{
    alert("This is a test box..");
}

setTimeout("mark()",5000);

错误:找不到函数mark()!!

还有一些其他问题..因为它适用于http://jsfiddle.net/russcam/6EXa9/,但它在我的应用程序中无法运行..所以你可以帮我调试吗?

还有什么原因..顺便说一句,我在GreaseMonkey脚本中运行它!

5 个答案:

答案 0 :(得分:11)

如果您使用的是GreaseMonkey,您定义的任何功能都由GM沙箱化,在主窗口中不可用。
但是当您使用任何本机函数时,例如 setTimeout alert ,它们在主窗口的上下文中被调用,例如; 当您调用 setTimeout 时,您实际上正在调用window.setTimeout()

现在您已定义的功能标记在主窗口中不存在,您要求 setTimeout 做的是评估字符串'mark()' 。超时触发时 调用window.eval( 'mark()' ),如上所述,未定义 window.mark 。所以你有几个选择:

1)在窗口对象上定义标记。 GM允许您通过 unsafeWindow 对象执行此操作,如下所示:

unsafeWindow.mark = function(){}
setTimeout( 'mark()', 10 );        //this works but is ugly, it uses eval

2)将对本地标记的引用传递给 setTimeout

function mark(){}
setTimeout( mark, 10 );        //this works too but you can't send parameters

但是如果你需要发送参数怎么办? 如果你已经在主窗口上定义了你的函数,那么eval方法将会起作用(但它很难看 - 不要这样做)

unsafeWindow.mark2 = function( param ) {
    alert( param )
}
setTimeout( 'mark2( "hello" )', 10 ); //this alerts hello

但是这个方法适用于带参数的函数,无论你是在主窗口还是在GM中定义它们 该调用包含在匿名函数中并传递到 setTimeout

setTimeout( function() {
    mark2( "hello" )
}, 10 );                              //this alerts hello

答案 1 :(得分:5)

尝试使用this setTimeout(mark,5000);

答案 2 :(得分:1)

如果您需要调用mark函数的唯一地方是超时尝试:

setTimeout(function() {
    alert("This is a test box..");
}, 5000);

答案 3 :(得分:1)

两个问题:

  1. 您无法在Greasemonkey中设置此setTimeout("mark()",5000);的定时器。请参阅GM pitfalls, Auto-eval Strings

  2. Firefox 4中目前存在错误。定时器内的警报会失败。见"alert + setTimeout = failure"。这就是Ander.by的答案不起作用的原因。

答案 4 :(得分:0)

是的,Grease Monkey部分可能会有所作为。 Grease Monkey几乎肯定会将JavaScript包装在一个函数中,以防止JavaScript与页面的JavaScript冲突。

您正在使用setTimeout的字符串形式,并且无法保证字符串将在哪个上下文中执行,尽管它可能位于全局范围内。只是因为您的函数在执行setTimeout的位置可见,并不意味着当字符串为eval时您的函数可见。

所以,不要使用setTimeout(永远)的字符串形式,使用Ander.by的方法或Walter Rumsby的匿名函数方法。