Ошибка в IE при ручном вызове обработчика событий при определенных условиях - PullRequest
15 голосов
/ 09 ноября 2010

Введение

  • Обратите внимание, я не ищу кодовое решение, а скорее хочу понять, почему это может произойти.
  • Ошибка возникает в IE (проверено 7 и 8), но не в Firefox, Chrome, Safari.

Описание

При ручном вызове функции, назначенной onclick, IE с броском a Error: Object doesn't support this action, если выполнены все следующие условия :

  1. Вы вызываете метод напрямую через свойство on[event] элемента.
  2. Вы не используете .call() или .apply().
  3. Вы передаете аргумент (любой аргумент, даже undefined).
  4. Вы пытаетесь присвоить возвращаемое значение переменной.

Нарушение любого из этих правил, и вызов успешен.

Кажется, что сама функция не имеет к этому никакого отношения. Пустая функция дает тот же результат.

Код

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

... но это не должно вызывать удивления, поскольку оно фактически совпадает с четвертой версией выше.

Ответы [ 3 ]

3 голосов
/ 14 ноября 2010

Что касается того, «почему» это было реализовано таким образом, то, вероятно, нет ответа извне. Хороший пример - когда бывший разработчик IE, изобретатель innerHTML, сталкивается с проблемами с самим innerHTML.

Спрашивать, почему тоже не нужно, потому что

  1. Вы не часто вызываете обработчики событий с параметрами явно
  2. Вы можете обойти эту проблему (как вы указали в своем вопросе)

Еще одна вещь, на которую следует обратить внимание: ваша аналогия слишком конкретна. Проблема не ограничивается assignment expression, вы можете воспроизвести ее с другими типами expressions:

undefined === elem.onclick( true )
typeof elem.onclick( true )
elem.onclick( true ) - 1
alert(elem.onclick( true ))
0 голосов
/ 10 ноября 2010

Попробуйте какую-нибудь функцию, которая на самом деле имеет один параметр и действительно что-то возвращает.Посмотрите, если это тоже выдает ошибку.Это может быть связано с параметрами и возвращаемым значением функции по умолчанию.Попробуйте и отправьте результаты обратно, пожалуйста.

РЕДАКТИРОВАТЬ

Если функция не вызывается, проблема может заключаться в разрешении свойства onclick.Может быть так, что вы на самом деле не вызываете определенную функцию, но код находит какую-то другую сборку в объекте IE, когда вы передаете true в качестве параметра.В любом случае это поведение не соответствует каким-либо спецификациям, поэтому мы можем назвать это ошибкой.Из этих IE есть много, как вы можете видеть из моих собственных вопросов.

IE 8 элемент с абсолютным позиционированием вне его родительской проблемы отсечения

IE8 bottom: 0 inпозиция: абсолютная ведет себя как позиция: фиксированная

0 голосов
/ 10 ноября 2010

Вы пытались использовать найденные инструкции здесь ?Он предлагает использовать такой код:

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...