You should also consider EventDelegation for that!
For that reason I prefer the addEventListener and foremost using it carefully and consciously!
FACTS:
- EventListeners are heavy .... (memory allocation at the client side)
- The Events propagate IN and then OUT again in relation to the DOM
tree. Also known as trickling-in and bubbling-out , give it a read
in case you don't know.
So imagine an easy example:
a simple button INSIDE a div INSIDE body ...
if you click on the button, an Event will ANYWAY
trickle in to BUTTON and then OUT again, like this:
window-document-div-button-div-document-window
In the browser background (lets say the software periphery of the JS engine) the browser can ONLY possibly react to a click, if it checks for each click done where it was targeted.
And to make sure that each possible event listener on the way is triggered, it kinda has to send the "click event signal" all the way from document level down into the element ... and back out again.
This behavior can then made use of by attaching EventListeners using e.g.:
document.getElementById("exampleID").addEventListener("click",(event) => {doThis}, true/false);
Just note for reference that the true/false as the last argument of the addEventListener method controls the behavior in terms of when is the event recognized - when trickling in or when bubbling out.
TRUE means, the event is recognized while trickling-in
FALSE means, the event is recognized on its way bubbling out
Implementing the following 2 helpful concepts also turns out much more intuitive using the above stated approach to handle:
- You can also use
event.stopPropagation() within the function
(example ref. "doThis") to prevents further propagation of the
current event in the capturing and bubbling phases. It does not,
however, prevent any default behaviors from occurring; for instance,
clicks on links are still processed.
- If you want to stop those behaviors, you could use
event.preventDefault() within the function (example ref.
"doThis"). With that you could for example tell the Browser that if
the event does not get explicitly handled, its default action should
not be taken as it normally would be.
Also just note here for reference again: the last argument of the addEventListener method (true/false) also controls at which phase (trickling-in TRUE or bubbling out FALSE) the eventual effect of ".stopPropagation()" kicks in.
So ... in case you apply an EventListener with flag TRUE to an element, and combine that with the .stopPropagation() method, the event would not even get through to potential inner children of the element
To wrap it up:
If you use the onClick variant in HTML ... there are 2 downsides for me:
- With addEventListener, you can attach multiple onClick-events to the same, respectively one single element, but thats not possible using onClick (at least thats what I strongly believe up to now, correct me if I am wrong).
- Also the following aspect is truly remarkable here ... especially the code maintenance part (didn't elaborate on this so far):
In regards to event delegation, it really boils down to this. If some
other JavaScript code needs to respond to a click event, using
addEventListener ensures you both can respond to it. If you both try
using onclick, then one stomps on the other. You both can't respond if
you want an onclick on the same element. Furthermore, you want to keep your behavior as separate as you can from the HTML in case you need to change it later. It would suck to have 50 HTML files to update instead of one JavaScript file.
(credit to Greg Burghardt, addEventListener vs onclick with regards to event delegation )
- This is also known by the term "Unobtrusive JavaScript" ... give it a read!