2011-05-07 61 views
6

這是我的代碼:Javascript:函數已定義,但錯誤表示函數未找到! (怪)

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

setTimeout("mark()",5000); 

錯誤:函數標記()未找到!

還有一些其他問題..因爲它在http://jsfiddle.net/russcam/6EXa9/上工作,但它不在我的應用程序中工作..所以你能幫我調試嗎?

還有什麼可以的原因..順便說一句,我在GreaseMonkey腳本里面運行這個!

+2

是另一個函數中定義的函數,通過任何機會呢? – 2011-05-07 07:51:46

+0

你使用的是什麼環境?工作正常 - http://jsfiddle.net/russcam/6EXa9/ – 2011-05-07 07:52:28

+0

這不工作...對我來說..我不明白爲什麼? 該函數不在任何函數內,其全局! – 2011-05-07 08:07:39

回答

11

如果您使用GreaseMonkey,則您定義的任何函數都由GM對沙箱進行沙箱處理,並且在主窗口中不可用。
但是,當您使用任何本機功能時,如setTimeout警報,它們在主窗口的上下文中調用,例如: 當你調用的setTimeout你實際上是在呼籲window.setTimeout()

現在你已經定義的函數,馬克不會在主窗口存在,你問的setTimeout做的是評估字符串「標誌()」。當超時觸發 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 
5

嘗試使用thissetTimeout(mark,5000);

+0

這沒有解決問題! :( – 2011-05-07 08:19:23

+0

我在setTimeout函數本身中的功能推了..併爲我做了詭計..但不明白以前發生了什麼! – 2011-05-07 08:41:53

1

如果您需要調用mark功能從你超時嘗試的唯一的地方:

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

是的,油猴部分可能會有所作爲。 Grease Monkey幾乎可以將JavaScript包裝在一個函數中,以防止JavaScript與頁面的JavaScript衝突。

您正在使用字符串形式的setTimeout,並且不能保證字符串將在哪個上下文中執行,儘管它可能位於全局範圍內。僅僅因爲你的函數在執行setTimeout時可見,並不意味着當字符串爲eval ed時,你的函數將是可見的。

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

1

兩個問題:

  1. 您不能設置像這樣setTimeout("mark()",5000);在Greasemonkey的定時器。請參閱GM pitfalls, Auto-eval Strings

  2. 目前Firefox 4中存在一個錯誤。警報將在計時器內失敗。請參閱"alert + setTimeout = failure"。這就是爲什麼Ander.by的答案不起作用。