Ошибка в IE при ручном вызове обработчика событий, учитывая определенные условия
Введение
- Обратите внимание: я не ищу решение для кода, а скорее понимаю, почему это может произойти.
- Ошибка возникает в 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
... но это не должно быть большим сюрпризом, так как это фактически то же самое, что и четвертая версия выше.
Ответы
Ответ 1
Что касается "почему", это было реализовано таким образом, то, по-видимому, ответа не было. Хорошим примером является то, что бывший разработчик IE, изобретатель innerHTML, сталкивается с проблемами с самой innerHTML.
Спросить, почему это также не нужно, потому что
- Вы не часто вызываете обработчики событий с параметрами явно
- Вы можете решить проблему (как вы сказали в своем вопросе)
Еще одно замечание - ваша аналогия слишком специфична. Проблема не ограничивается assignment expression
, вы можете воспроизвести ее другими типами expressions
:
undefined === elem.onclick( true )
typeof elem.onclick( true )
elem.onclick( true ) - 1
alert(elem.onclick( true ))
Ответ 2
Вы пробовали использовать найденные инструкции здесь? Он предлагает использовать такой код:
var fireOnThis = document.getElementById('someID');
var evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent( 'click', true, true, window, 1, 12, 345, 7, 220, false, false, true, false, 0, null );
fireOnThis.dispatchEvent(evObj);
Ответ 3
Попробуйте использовать некоторую функцию, которая фактически имеет один параметр и фактически возвращает что-то. Посмотрите, вызывает ли это ошибку. Это может иметь какое-то отношение к параметрам и возвращаемому значению функции по умолчанию. Попробуйте и отправьте результаты назад, пожалуйста.
ИЗМЕНИТЬ
Если функция не вызвана, проблема может заключаться в разрешении свойства onclick. Возможно, вы каким-то образом не назовете свою определенную функцию, но код находит какую-то другую сборку в объекте IE, когда вы передаете true как параметр. В любом случае это поведение не соответствует спецификациям, поэтому мы можем назвать его ошибкой. Из этих IE есть много, как вы можете видеть из моих собственных вопросов.
IE 8 абсолютный позиционированный элемент вне проблемы отсечения родительского элемента
Нижняя часть IE8: 0 в позиции: абсолютный ведет себя как позиция: исправлено