Az események terjedésének egyszerűsített magyarázata a JavaScript-ben.

Képzelje el ezt a forgatókönyvet:

Felhasználói listát készít. Megjeleníti a nevüket, kedvenc színeiket és e-mailjeiket. Ha rákattint egy felhasználóra (a táblázat egy sora), akkor azt szeretné, hogy a felhasználói rekordba vezessen. Kivéve, ha rákattint az e-mailre, akkor fel kell ugrania egy e-mail párbeszédpanelt.

Lehet, hogy írsz egy ilyen kódot (itt egy táblázatot használunk, mert könnyen érthető - bár természetesen valami sokkal bonyolultabbat is használhatunk a projektünkben):


    
Name Colors Email
Susie Blue, Red [email protected]

Ha rákattintana az egyik ilyen sorra, akkor valószínűleg hozzáad egy onClickfunkciót a sorhoz. Így, ha a sor bármely pontjára kattintanak, egyenesen a felhasználói rekordhoz juthatnak.

Az e-mail gondozásához megtesszük a ef> tag on the text.

But wait! The email dialog pops up, but we also navigate to the user record. That’s not what we want! How do we handle this? Enter event propagation.

Event propagation in a nutshell.

Event propagation is a way to describe the “stack” of events that are fired in a web browser. In our table example above, clicking on the a tag is the first event that we will fire, but there are other events too.

To understand that concept, you must understand that the elements on a web browser are nested. They do not cover each other up. So a click on the a tag also clicks on the row, the table, the div in which the table is nested, and anything else all the way out to document , the complete container that holds everything in your browser.

If we’ve put any other onClick events inside of these other elements, they will also be fired when we click on the a link in the table. That’s why we will be directed to the user record when we click on the email link. It’s going to perform both the onClick function for the a link and the onClick function for the row.

Bubbles

The movement of events “up” from the most-nested element ( a) out to the least-nested ( document) is referred to as “bubbling.” If events start in the “outer-most” element and moved “down,” that is referred to as “trickling.” All you probably care about is the default behavior: bubbling.

How to use event propagation to your advantage

Honestly, I hadn’t run into any use-case for caring about event propagation until this week, when I needed to build a table with a checkbox in it. Unfortunately for me, when I tried to set up the checking functionality, it took me to the record. Fortunately, I did some training earlier (see references below) that gave me a clue on exactly what I had to Google.

You probably already know that when you create an onClick event, it is passed to whatever function you call.

So here, I was able to write:

handleCheck = e => { e.stopPropagation() // talk to my API, set the record as "done" or not } []

That e.stopPropagation() halts this “bubbling” of events “up” through the DOM. We stop all of the other events in the stack. Awesome!

So my whole row gets to behave as it should, and this one little checkbox can have a special functionality.

preventDefault vs. stopPropagation

You may be thinking: why not just use e.preventDefault()? That is indeed the first thing I tried, but there simply is no default behavior for a span (unlike a form, whose default submit behavior will refresh the page).

Cut-and-paste example

I write a lot of React, so I’m giving an example in React. But this would work the same in plain old HTML and JavaScript, using whatever method you’ve got to add event listeners:

 console.log('outer div')}> console.log('middle div')}> console.log('innermost div')}> Click me! 

Event propagation: bubbles without the champagne.

References

  • Big shouts to Wes Bos who first introduced me to this concept in his #Javascript30 course. I would have had no idea what to Google when I ran into the problem identified in the table example above if I hadn’t first seen it during the course.
  • This Stack Overflow answer, which nicely sums up some of the more nuanced bits of event capture and propagation.