Функция определена, но выдает ошибку.. Функция не найдена! (Странно)

#javascript #asynchronous #dom-events #greasemonkey

#javascript #асинхронный #dom-события #greasemonkey

Вопрос:

Это мой код :

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

setTimeout("mark()",5000);
  

Ошибка: Функция mark() не найдена!!

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

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

Комментарии:

1. Функция случайно не определена внутри другой функции?

2. какую среду вы используете? Работает нормально — jsfiddle.net/russcam/6EXa9

3. Это не работает… для меня.. Я не понимаю , почему ? Функция не находится внутри какой-либо функции, она глобальная !

4. Это должно сработать .. но это не работает!

5. Кстати .. это часть скрипта grease monkey .. имеет ли это значение?

Ответ №1:

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

Теперь функция, которую вы определили, mark, не существует в главном окне, и то, что вы просите setTimeout сделать, это вычислить строку ‘mark()’. При срабатывании тайм-аута window.eval( 'mark()' ) вызывается и, как обсуждалось, window.mark не определяется. Итак, у вас есть пара вариантов:

1) Определите метку на объекте window. GM позволяет вам делать это через небезопасный объект Windows, подобный этому:

 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
  

Ответ №2:

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

Комментарии:

1. Я вставил функцию в саму функцию setTimeout .. и это помогло мне .. но раньше я не понимал, что происходит!!

Ответ №3:

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

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

Ответ №4:

Две проблемы:

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

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

Ответ №5:

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

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

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