0

Consider this snippet:

<div onkeypress="console.log('parent');">
    <input type="text" onkeypress="console.log('child');">
</div>

Two nested elements both with an onkeypress -event. When I put the cursor in the resulting input and hit a key on my keyboard I get

child
parent

logged to the console in that order. My question is if I can count on it ALWAYS firing in that order. I.e. that the innermost element always will fire first?

swelet
  • 8,192
  • 5
  • 33
  • 45
  • 2
    This is a good explanation of event bubbling and what you can expect/control: http://www.quirksmode.org/js/events_order.html also read this: http://stackoverflow.com/questions/4616694/what-is-event-bubbling-and-capturing – Rob M. Feb 18 '16 at 19:25

3 Answers3

2

Yes you can, as noted on MDN and W3 you can count on the inner most event to fire first and as the action bubbles up, subsequent events will fire. There is a difference on what browsers consider a keypress event.

From QuirksMode: (Capturing fires outside to inside i.e. down arrow and bubbling fires inside to outside i.e. up arrow).

     Capturing-> | |  / \ <-Bubbling
-----------------| |--| |-----------------
| element1       | |  | |                |
|   -------------| |--| |-----------     |
|   |element2    \ /  | |          |     |
|   --------------------------------     |
|        W3C event model                 |
------------------------------------------

Using an event listener you can dictate capturing vs bubbling with the 3rd parameter.

element1.addEventListener('keypress',myScript,true) // Capture element1.addEventListener('keypress',myScript,false) // Bubble*default

object.addEventListener("keypress", myScript, false); == <div onkeypress="myScript()">

One thing to note, IE does not follow the same model, but you can still count on bubbling, i.e. inside out.

Vinny M
  • 762
  • 4
  • 14
1

Yes it will. No matter if you add the event handler in the html (like in your example) or in the js file. And no matter of the order you register the event handlers in the javascript files because, as explained by Rob & Vinny, the event 'bubbles' from the element. The keypress event starts from the dom element input then bubbles to his parent, and to his parent's parent and so on. Therefore the event handlers will be triggered in the same order.

Is it all you need to know ? If you have a specific use case for these 2 separate handlers you can explain what it is and I can try to code a solution because in your example I can't see how it can be useful to have 2 actions for the same event on the same element.

EDIT : then why not using a global listener on the document with a check if the element on focus is an input ?

Example on JSFiddle :

document.addEventListener('keypress', function(e){
  var key = String.fromCharCode(e.which),
      targetElt = e.target;

  if (key === 'a'){
    console.log('-- Action when "a" is pressed')
    if (targetElt.nodeName === 'INPUT') {
      console.log('-- Action when "a" is pressed and the focus is on an input');
    }
  } 
}, false);

If you press 'a' only the first console.log is called, if you press 'a' when the input is focused, both console.log are called.

If you have multiple keys I would recommend to use a switch statement instead of a if / else if / else

Thanks

OxyDesign
  • 754
  • 5
  • 6
  • Ok thanks. It's a dummy example, I'm actually working in React and the question stems from wanting to have a few global keyboard shorctuts, a few of them with added behaviour if specific elements are focused. Vinny also states that bubbling is the standard behaviour by the way. – swelet Feb 19 '16 at 05:18
  • I edited my answer with an example. Is it what you expected ? – OxyDesign Feb 19 '16 at 08:50
0

It depends on the browser. However you can decide the order of execution, by placing addEventListener() on the element.

This guide explains it in deepth: http://www.quirksmode.org/js/events_order.html

jozhe
  • 197
  • 10
  • *"It depends on the browser."* How so? Can you elaborate? – Felix Kling Feb 18 '16 at 23:06
  • Ok in all browsers nowadays, there is first capturing and than bubbling of the event. Capturing is ignored without addEventListener(), set on true. But it wont work the same for IE < 9. So he shouldn't rely on the default behaviour. – jozhe Feb 19 '16 at 09:34
  • Well, the fact that capturing is not supported by older browsers doesn't mean that bubbling doesn't work the same in every browser :) – Felix Kling Feb 19 '16 at 15:04