2012-03-01 2 views
4

Я столкнулся с странностью при использовании Prototype для обработки событий щелчка. Если вы нажмете кнопку в приведенном ниже коде, она вызовет три предупреждения: «Нажмите 1», «Нажмите 2» и «Нажмите 3». Современные браузеры будут вызывать слушателей в том порядке, в котором они зарегистрированы, в то время как IE8 (и, возможно, более старые версии IE) будут ссылаться на них в обратном порядке. Я нахожу это странным, потому что думал, что Prototype поддерживает и выполняет очередь слушателей, которая должна быть независимой от браузера. Разве это не так? Если нет, слушатели событий должны быть запущены в определенном порядке или они асинхронны и, следовательно, их порядок не имеет значения?Порядок прослушивания нескольких слушателей

<button id="button">Click me</button> 
    <script type="text/javascript"> 
     $('button').observe('click', function(event) { 
      alert('Click 1'); 
     }); 
     $('button').observe('click', function(event) { 
      alert('Click 2'); 
     }); 
     $('button').observe('click', function(event) { 
      alert('Click 3'); 
     }); 
    </script> 

ответ

13

Prototype опирается на основной механизм запуска браузера для заказа (не все библиотеки, см. Ниже). Порядок, в котором запускаются обработчики событий, не был гарантирован исходными событиями DOM. Из DOM2 Events specification:

Хотя все EventListeners на EventTarget гарантированно быть вызвано любое событие, которое получено этим EventTarget, никакой спецификации производится в том порядке, в котором они будут получать события в отношении к другие EventListeners на EventTarget.

Подавляющее большинство браузеров (Chrome, Firefox, Opera и т. Д.), Включая IE9, запускают обработчики в том порядке, в котором они были прикреплены. IE8 и раньше делают это наоборот.

Поздние DOM3 event spec, все еще в стадии разработки, вводит требование о том, что они будут уволены в порядке регистрации (что делает большинство браузеров):

Далее, реализация должна определить слушателей событий кандидатов текущего целевого объекта , Это должен быть список всех прослушивателей событий, которые были зарегистрированы в текущем целевом объекте в порядке их регистрации.

... который, вероятно, часть того, почему IE9 делает это сейчас (IE9 заметно улучшена поддержка от Microsoft для стандартов событий, добавление addEventListener и т.д.).

Некоторые библиотеки JavaScript (например, jQuery) do гарантируют заказ независимо от браузера, добавляя только один обработчик для каждого события на элемент и сохраняя свой собственный список обработчиков кода пользователя для запуска.

0

Согласно этому bug report, это, кажется, существующая ошибка, и что это на самом деле браузер зависит.

Резюмируя отчет:

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

0

В отформатированном комментарии от @ T.J. Ответ Кроудера, я протестировал, какие современные браузеры фактически запускают слушателей в порядке регистрации.

2016-10-06: результаты следующие: chrome 53, firefox 49, safari 9, opera 40, т.е. 11 и край 13 через виртуальный бокс на хост-компьютере Mac.

Код моего теста можно найти здесь: https://github.com/lingtalfi/browsers-behaviours/blob/master/listeners-execution-order/listeners.md

Смежные вопросы