Введение
- Обратите внимание, я не ищу кодовое решение, а скорее хочу понять, почему это может произойти.
- Ошибка возникает в IE (проверено 7 и 8), но не в Firefox, Chrome, Safari.
Описание
При ручном вызове функции, назначенной onclick
, IE с броском a 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's 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 реализован таким образом.
Большое спасибо.
РЕДАКТИРОВАТЬ: Чтобы прояснить одну вещь, ничего с реальной функцией, кажется, не имеет никакого значения. Называя параметры, не называя их, возвращая аргумент, возвращая буквальное значение, возвращая неопределенное, все это не имеет никакого эффекта.
Вероятно, потому что функция, кажется, никогда не вызывается. Как я отметил в комментарии ниже, код, приводящий к этому вызову, работает нормально, поэтому это не проблема синтаксического анализа. Но когда переводчик добирается до этого, он видит:
Переменная + AssignmentOperator + DOMElement + EventHandler + CallOperator + Argument
... и выдает ошибку. Никакие манипуляции, которые я делаю, не имеют никакого значения. Допустимое удаление любого из них, и ошибка исчезает.
Если я добавлю в середину переменную, которая хранит обработчик, добавьте ее из переменной, с которой он работает.
var temp = elem.onclick;
result = temp( true ); // works
... но это не должно вызывать удивления, поскольку оно фактически совпадает с четвертой версией выше.