Event listeners are provided with an event
object that represents an actively dispatched event. An event
object contains lots of information and functionality related to an event. We will look at the various event properties, constants and methods you have at your disposal on an event
object and the Event
constructor.
Hey Alex,
I have two questions:
You introduce the event object including the currentTarget property. At first glance, we can use either this or event.currentTarget in our handler function to achieve the same result:
const button = document.querySelector("button"); function listener(event) { console.log("this: ", this); console.log("event.currentTarget: ", event.currentTarget); } button.addEventListener("click", listener, { capture: false, });
Now, you discussed the gotchas with using this, but is there any rationale of choosing one over the other for most cases if we aware of said gotchas?
For my second question: From the componentPath example we can see that the DOM stucture is as follows: button > div.parent > div.child > button
If I change div.parent to p.parent with everything else being equal our listener will not trigger when interacting with div.child or button any longer. What is the determining factor when it comes to an event traversing the DOM based on the HTML element type?
Best regards, David
Hi David,
Thanks for reaching out. Let's dive into your questions.
Now, you discussed the gotchas with using
this
, but is there any rationale of choosing one over the other for most cases if we aware of said gotchas?
You are completely free to choose whatever approach you like. I personally find myself avoiding using this
as it can be confusing for some folks and is subject to a few gotchas. Using this
means you need to be aware of where the function is being run as this
is determined by the functions call site.
If I change div.parent to p.parent with everything else being equal our listener will not trigger when interacting with div.child or button any longer.
I think you will find the answer to this one if you open your dev tools. You will see that by changing .parent
from a div
to a p
, your .parent
element is no longer a parent element. This is because the p.parent
will be closed automatically and not allow block element children.
From MDN:
"Paragraphs are block-level elements, and notably will automatically close if another block-level element is parsed before the closing </p> tag. See "Tag omission" below."
What is the determining factor when it comes to an event traversing the DOM based on the HTML element type?
event.composedPath()
returns all the parent EventTarget
s from the target of the event (event.target
) up to the root EventTarget
(the window
). All Element
s are EventTarget
s so any parent element of the target of the event (event.target
) will be included in event.composedPath()
.
Any more questions, let me know.
Cheers
Thanks for elaborating Alex!
I find the explanation of MDN to be a bit odd though:
"Paragraphs are block-level elements,..." divs are also block-level elements. The phrasing suggests that being a block-level element is of importance here but it seems only the Tag omission is really relevant.
I think they are trying to call out two things:
p
is a block element (similar to div
)p
will automatically close if a child of p
is found to be a block element (the tag closing behaviour)I recently came across this video which explores some of the strangeness of the p
tag: Magic tricks with the HTML parser