JavaScript: функция определена, но ошибка говорит .. Функция не найдена!(Странный) - PullRequest
6 голосов
/ 07 мая 2011

Это мой код:

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

setTimeout("mark()",5000);

Ошибка: метка функции () не найдена !!

Есть еще одна проблема .. как она работает на http://jsfiddle.net/russcam/6EXa9/, но она не работает в моем приложении ... так что вы можете помочь мне отладить это?

В чем еще может быть причина ... Кстати, я запускаю это внутри скрипта GreaseMonkey!

Ответы [ 5 ]

11 голосов
/ 07 мая 2011

Если вы используете GreaseMonkey, любые определяемые вами функции помещаются в песочницу GM и недоступны в главном окне.
Однако при использовании любой из встроенных функций, таких как setTimeout или alert , они вызываются в контексте основного окна, например; когда вы звоните setTimeout , вы на самом деле звоните window.setTimeout()

Теперь функция, которую вы определили, mark не существует в главном окне, и то, что вы просите 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
5 голосов
/ 07 мая 2011

попробуйте использовать это setTimeout(mark,5000);

1 голос
/ 07 мая 2011

Два вопроса:

  1. Вы не можете установить таймеры как это setTimeout("mark()",5000); в Greasemonkey.См. Подводные камни GM, Строки с автоматическим вычислением .

  2. В настоящее время в Firefox 4 есть ошибка. Предупреждения будут сбиваться внутри таймеров.См. «alert + setTimeout = fail» .Вот почему ответ Ander.by не работает.

1 голос
/ 07 мая 2011

Если единственное место, из которого вам нужно вызвать функцию mark, это ваш тайм-аут:

setTimeout(function() {
    alert("This is a test box..");
}, 5000);
0 голосов
/ 07 мая 2011

Да, часть Grease Monkey может иметь значение. Grease Monkey почти наверняка обернет ваш JavaScript в функцию, чтобы ваш JavaScript не конфликтовал с JavaScript на странице.

Вы используете строковую форму setTimeout, и нет гарантии, в каком контексте будет выполняться строка, хотя, вероятно, она находится в глобальной области видимости. То, что ваша функция видна там, где вы выполняете setTimeout, не означает, что ваша функция будет видна, когда строка eval ed.

Итак, не используйте строковую форму setTimeout (никогда), используйте подход Ander.by или подход анонимной функции Уолтера Рамсби.

...