Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The Order of Multiple Event Listeners

I've come across an oddity while using Prototype to handle click events. If you click the button in the code below, it will trigger three alerts: 'Click 1', 'Click 2' and 'Click 3'. Modern browsers will invoke the listeners in the order they are registered in, while IE8 (and perhaps older IE versions as well) will invoke them in the opposite order. I find this odd because I thought Prototype maintained and executed a queue of listeners, which should be browser independent. Is this not so? If not, are event listeners supposed to be run in a certain order or are they asynchronous and thus their order irrelevant?

    <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>
like image 964
Johan Fredrik Varen Avatar asked Mar 01 '12 07:03

Johan Fredrik Varen


1 Answers

Prototype relies on the browser's underlying firing mechanism for order (not all libraries do, see below). The order in which event handlers are fired was not guaranteed by the DOM events stuff originally. From the DOM2 Events specification:

Although all EventListeners on the EventTarget are guaranteed to be triggered by any event which is received by that EventTarget, no specification is made as to the order in which they will receive the event with regards to the other EventListeners on the EventTarget.

The vast majority of browser implementations (Chrome, Firefox, Opera, etc.), including IE9, fire the handlers in the order in which they were attached. IE8 and earlier do it the other way around.

The newer DOM3 event spec, still a work in progress, introduces the requirement that they be fired in order of registration (what most browsers do):

Next, the implementation must determine the current target's candidate event listeners. This must be the list of all event listeners that have been registered on the current target in their order of registration.

...which is probably part of why IE9 does that now (IE9 markedly improved Microsoft's support for the events standards, adding addEventListener, etc.).

Some JavaScript libraries (jQuery for instance) do guarantee the order regardless of the browser, by attaching only a single handler per event per element and maintaining their own list of user code handlers to fire.

like image 86
T.J. Crowder Avatar answered Oct 19 '22 17:10

T.J. Crowder