Введение
- Обратите внимание: я не ищу решение для кода, а скорее понимаю, почему это может произойти.
- Ошибка возникает в IE (проверены 7 и 8), но не Firefox, Chrome, Safari.
Описание
При ручном вызове функции, назначенной onclick
, IE сбрасывает Error: Object doesn't support this action
, если выполняются все следующие условия:
- Вы вызываете метод напрямую через свойство
on[event]
. - Вы не используете
.call()
или.apply()
. - Вы передаете аргумент (любой аргумент, даже
undefined
). - Вы пытаетесь присвоить возвращаемое значение переменной.
Нарушить любое из этих правил, и вызов завершается успешно.
Сама функция не имеет к этому никакого отношения. Пустая функция дает тот же результат.
код
var elem = document.getElementById('test'); // simple div element.
var result; // store result returned.
function test_func(){}; // function declaration.
// function expression behaves identically.
elem.onclick = test_func; // assign test_func to element onclick.
// DIRECT CALL
test_func(); // works
test_func( true ); // works
result = test_func(); // works
result = test_func( true ); // works
// DIRECT CALL, CHANGING THE CONTEXT TO THE ELEMENT
test_func.call( elem ); // works
test_func.call( elem, true ); // works
result = test_func.call( elem ); // works
result = test_func.call( elem, true ); // works ******** (surprising)
// CALL VIA ELEMENT, USING .call() METHOD, CHANGING THE CONTEXT TO THE ELEMENT
elem.onclick.call( elem ); // works
elem.onclick.call( elem, true ); // works
result = elem.onclick.call( elem ); // works
result = elem.onclick.call( elem, true ); // works ******** ( very surprising)
// CALL VIA ELEMENT
elem.onclick(); // works
elem.onclick( true ); // works
result = elem.onclick(); // works
result = elem.onclick( true ); // Error: Object doesn't support this action
Резюме
Опять же, мне не нужно решение для кода. Скорее, мне любопытно, есть ли у кого-нибудь представление о том, почему IE реализуется таким образом.
Большое спасибо.
РЕДАКТИРОВАТЬ: Чтобы прояснить одно, ничего с фактической функцией, похоже, не имеет никакого значения. Именование параметров, а не их именование, возврат аргумента, возврат литерала, возврат undefined, все это не имеет эффекта.
Это, вероятно, потому, что функция, кажется, никогда не вызвана. Как я заметил в комментарии ниже, код, ведущий к этому вызову, работает нормально, поэтому он не является проблемой синтаксического анализа. Но когда переводчик добирается до этого, он видит:
Variable + AssignmentOperator + DOMElement + EventHandler + CallOperator + Аргумент
... и выдает ошибку. Никаких манипуляций, я, кажется, не имеет никакого значения. Действительное удаление любого из них, и ошибка исчезает.
Если я помещаю добавленную переменную в середину, которая хранит обработчик, тогда запустите его из переменной, в которой она работает.
var temp = elem.onclick;
result = temp( true ); // works
... но это не должно быть большим сюрпризом, так как это фактически то же самое, что и четвертая версия выше.