Разве первый фрагмент не должен работать нормально?
Да, возможно, так и должно быть. Но это не так. :-) К счастью, есть простой обходной путь (и лучше, чем arguments.callee
, который имеет проблемы [см. Ниже]).
проблема
Проблема в том, что выражения именованных функций (NFE, которые у вас есть) не работают правильно в JScript (IE) или в некоторых других реализациях в дикой природе. Юрий Зайцев ( kangax ) провел тщательное исследование NFE и написал эту полезную статью о них.
Выражение именованной функции - это то, где вы присваиваете функции имя и используете оператор функции в качестве правого значения (например, правую часть присваивания или передаете его в функцию вроде attachEvent
), вот так:
var x = function foo() { /* ... */ };
Это выражение функции, и функция названа. Возможно, это должно работать, но во многих реализациях в дикой природе, включая IE JScript, это не так. Именованные функции работают, и работают выражения анонимных функций, но не именованные функциональные выражения. ( Редактировать Я не должен был говорить не работает , потому что в некоторых отношениях они работают. Я должен был сказать, что не работает должным образом ; больше в Статья Юрия и мой ответ на ваш дополнительный вопрос .)
Решение
Вместо этого вы должны сделать это:
var x = foo;
function foo() { /* ... */ };
... что, в конце концов, приводит к одному и тому же.
Так что в вашем случае просто сделайте это:
document.getElementById('iframeid').attachEvent("onreadystatechange", onIframeReadyStateChange);
function onIframeReadyStateChange() {
if (event.srcElement.readyState != "complete") { return; }
event.srcElement.detachEvent("onreadystatechange", onIframeReadyStateChange);
// code here was running every time my iframe's readyState
// changed to "complete" instead of only the first time
}
Это имеет тот же эффект, что и вы, но без проблем с реализацией.
Проблема с arguments.callee
(Это немного не по теме, но ...) Вы правы, избегая использования arguments.callee
. В большинстве реализаций его использование приводит к огромным накладным расходам , замедляя вызов функции на порядок (да, действительно; и нет, я не знаю почему). Это также запрещено в новом «строгом режиме» ECMAScript 5 (и «строгий режим» - это, в основном, хорошая вещь).