Event Propagation and Event Delegation
This is a key part of JavaScript functionality outlined in the W3C Document Object Model (DOM) Level 2 Events Specification.
Event Propagation #
This flow occurs when an event takes place such as a click, hover, or mousedown. The function is then triggered on each part of each stage of each flow. That was a mouthful. But think of it this way, starting from the topmost to the bottom and back from the bottom to the top (3 -> 2 -> 1 -> 1 -> 2 -> 3). Event capturing first then event bubbling.
<div onclick="foo(this)">3
<div onclick="foo(this)">2
<div onclick="foo(this)">1</div>
</div>
</div>
So each capture down and each bubble up would trigger an onclick and the resulting function foo(this)
if the inner most div (with innerText = “1”) was clicked. The scope of this
will then change depending on when it was called since this
is not assigned a value until the function has been invoked while the event.target
remains the same throughout the event propagation as the originating element clicked.
this
is the current elementtarget
is the originating element
Event Capturing #
- First stage of event propagation
- Event captures from top to bottom elements
- This stage does not occur in IE <9
Event Bubbling #
- Second stage of event propagation
- Event bubbles from bottom to top elements
onfocus
andonblur
events don’t bubble up
Event Delegation #
Typically when building webapps a component would have a list part. There would be no need to attach an event listener to each list item, rather it would be more efficient to listen to the list itself (ol
or ul
). Then using event delegation by checking the event’s target (event.target
) to determine if the user has indeed clicked on a list item (li
) part of the list. If the user has then we trigger the delegated function, for example, adding a check mark to the list item when selected.
- Add event listener to the parent element
- Check
event.target
Polyfilling Issues #
Some browsers are not W3C-compliant, such as versions of IE and Netscape. To address this, some polyfilling must be performed or inputting cross-browser code.
Events are stopped by
event.cancelBubble = true; // IE
event.stopPropagation(); // All other W3C-compliant browsers
Event targets are from a hybrid approach since IE takes it from srcElement
var target = event.target || event.srcElement;