Порядок прослушивания нескольких событий - PullRequest
5 голосов
/ 01 марта 2012

Я столкнулся со странностью при использовании 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>

Ответы [ 3 ]

15 голосов
/ 01 марта 2012

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

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

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

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

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

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

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

1 голос
/ 06 октября 2016

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

2016-10-06: В результате получаются все следующие браузеры: chrome 53,Firefox 49, Safari 9, Opera 40, то есть 11 и Edge 13 через виртуальный ящик на хосте Mac.

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

0 голосов
/ 01 марта 2012

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

Подводя итог отчета:

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

...