8

If an element has multiple event listeners attached, will the order of execution be based on where/when the events are bound (located in the code from top to bottom). Guaranteed, 100% of the time?

Or is there any "randomness" involved in this. What about mixing jQuery and vanilla event listeners on the same element?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Bruffstar
  • 1,249
  • 1
  • 10
  • 18
  • 1
    Do you mean that you declare multiple eventListeners for the same event ? – Mteuahasan Aug 06 '15 at 09:40
  • Try to show your code – HassanUsman Aug 06 '15 at 09:42
  • Do you mean the order of firing listeners? – Mehdi Aug 06 '15 at 09:42
  • No, I mean eg. I have a button that has 3 separate click events attached to it in different areas of the code, doing different things. I want to add a 4th click event that happens first, if I place this at the top, will it 100% be fired first. (This is all based on the fact that I cannot modify the code to have 1 click event firing off different functions) – Bruffstar Aug 06 '15 at 09:44
  • I have no code, its a general question – Bruffstar Aug 06 '15 at 09:45

3 Answers3

5

(Assuming you are talking about the same event type and element)The event handlers will get executed in the order in which the handlers are registered. This is true when you are dealing with either jQuery handles or javascript handlers(the capture phase runs before bubbling) alone, not mixed.

When you have mixed handlers, jQuery will add a vanila handler when it tries to register a handler of a type for the first time for an element, so it will follow the order of vanilla handlers in order(but all the jQuery handlers will be executed when the jQuery's own native handler is triggered)

var el = document.getElementById('clickme');

el.addEventListener('click', function() {
  snippet.log('o - 1');
});
el.addEventListener('click', function() {
  snippet.log('o - 2');
});

$('#clickme').click(function() {
  snippet.log('jq - 1(o -3)')
});
el.addEventListener('click', function() {
  snippet.log('o - 4');
});
$('#clickme').click(function() {
  snippet.log('jq - 2')
});
$('#clickme').click(function() {
  snippet.log('jq - 3')
});
el.addEventListener('click', function() {
  snippet.log('o - 5');
});
el.addEventListener('click', function() {
  snippet.log('o - 6');
});
$('#clickme').click(function() {
  snippet.log('jq - 4')
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

<button id="clickme">This is for testing</button>
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • This is great to know thanks. By moving your first jQuery event to the top, it knocks out all jQuery events first, then the vanillas, very interesting. – Bruffstar Aug 06 '15 at 09:55
2

Historically there are two models of behavior.

Netscape said that the event on element1 takes place first. This is called event capturing.

Microsoft maintained that the event on element2 takes precedence. This is called event bubbling.

Now you can decide which one (top to bottom or bottom to top) to use by setting|unsetting the last parameter of AddEventListener:

element1.addEventListener('click',doSomething2,true);
element2.addEventListener('click',doSomething,false);

If the last argument is true the event handler is set for the capturing phase, if it is false the event handler is set for the bubbling phase.

Here everything is explained perfectly.

onerror
  • 606
  • 5
  • 20
1

This is a very useful discussions for EventListeners. I've tried on several occasions to use the syntax for example...

element.addEventListener("event", callFunction(this.val))

I had a lot of issues to get that to feed well to a separate function. Better to link the function directly to the event if possible. ie.

element.event = function() { /* enter your function contents */ };

However, I can remember possible reasons why you wouldn't always be able to do this on every occasion. Perhaps on the event you are calling to an element that isn't cannot yet be defined or targeted by the script.