Back 2 Basics

Capturing and Bubbling ? No! Bungee Jumping

May 02, 2020

Hi! I am Meghna (My name would be required later in an example, hence, mentioning now).

You must be wondering why I used bungee jumping.

Right ?

I’ll come back to this in a moment.

For now,

Follow along!

Some Story…

family

Mine is a family of four composed of my dad, my mum, my elder brother and me. (I have mentioned them all in decreasing order of ages).

Yes! I’m the youngest and the most pampered.

I know what you’re thinking ;-)

Meghna ?

What am I to do with that knowledge ?

Hold On!

Have some patience.

Now,

Let’s consider a scenario where you wanna shake hands with me (I’d love to).

hand shake

But can do so only when one of the following conditions is satisfied :-

First, you can shake hands with my family members in decreasing order of age. ie. my dad first, then mum, brother & finally me!

Second, shaking hands in increasing order of age. Yes! you guessed the order right. It’s first me, then brother, mum & finally dad.

You know what ?

We just understood what event capturing and bubbling is. Seriously!

The former, where you go down the heirarchy of shaking hands is an instance of event capturing.

Contrary to this, the latter, is event bubbling.

Enough of words.

Let’s see that in action!

This is how your basic html file should look like:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Bubbling and Capturing</title>

    <style>
      * {
        box-sizing: border-box;
        text-align: center;
      }
      div {
        min-width: 100px;
        min-height: 100px;
        padding: 20px;
        border: 3px solid black;
        margin: 20px;
        border-radius: 5px;
      }
      #dad {
        background-color: brown;
      }
      #mum {
        background-color: aqua;
      }
      #bro {
        background-color: blue;
      }
      #meg {
        background-color: rgb(228, 43, 74);
      }
    </style>
  </head>
  <body>
    <h1>Event Bubbling and Capturing</h1>
    <div id="dad">
      <div id="mum">
        <div id="bro">
          <div id="meg"></div>
        </div>
      </div>
    </div>
    <script src="./index.js"></script>
  </body>
</html>

Here, we have simply added four divs. The outermost represents my dad and the innermost me. Also, we have added some styling for simplicity and attached a javascript file about which we will talk later.

This is how it should look on the browser.

screenshot

Nice!

Now, let’s recall what .addEventListener() method does.

.addEventListener()


We all know that the first parameter refers to events like "click", "resize" etc., a function is passed as an argument to the second parameter. And yes, a boolean value (true/false) is passed as an argument to the third parameter.

If nothing is passed, the third argument is considered false.

addeventListener

For the third argument, true depicts event capturing and false event bubbling

If the third argument is not passed, it depicts bubbling

To read more about addEventListener() go here.

We’re ready to jump right on to my favourite part. Yes! it’s JavaScript.

Event Bubbling


Initially, we are not passing the third argument.

This is how your index.js file should look :

// Creating elements for respective ids
const dad = document.querySelector("#dad")
const mum = document.querySelector("#mum")
const bro = document.querySelector("#bro")
const meg = document.querySelector("#meg")

dad.addEventListener(
  "click",

  () => {
    console.log("Shaking hands with her dad.")
  }
  //default value is set to false, hence, Bubbling
)
mum.addEventListener(
  "click",
  () => {
    console.log("Shaking hands with her mum.")
  }
  // Bubbling
)
bro.addEventListener(
  "click",
  () => {
    console.log("Shaking hands with her brother.")
  }
  // Bubbling
)

meg.addEventListener(
  "click",
  () => {
    console.log("Shaking hands with Meghna!")
  }
  // Bubbling
)

Here, click event represents shaking of hands. ie, when you click the innermost pink coloured box, you will receive the following output on the console :

Shaking hands with Meghna!
Shaking hands with her brother.
Shaking hands with her mum.
Shaking hands with her dad.

Whoa!

You got to shake hands with me directly.

But the the propagation is still not complete.

Having shaken hands hands with me, you have to now shake hands with my brother, mum and dad too.

This is exactly what we call event bubbling. ie, we propagate from the bottom most div to the topmost div.

Event Capturing


Now, let’s see what happens when we pass true as the third argument for all the elements.

dad.addEventListener(
  "click",

  () => {
    console.log("Shaking hands with her dad.")
  },
  true // Capturing
)
mum.addEventListener(
  "click",
  () => {
    console.log("Shaking hands with her mum.")
  },
  true // Capturing
)
bro.addEventListener(
  "click",
  () => {
    console.log("Shaking hands with her brother.")
  },
  true // Capturing
)

meg.addEventListener(
  "click",
  () => {
    console.log("Shaking hands with Meghna!")
  },
  true // Capturing
)

On clicking the innermost div, we get the following output:

Shaking hands with her dad.
Shaking hands with her mum.
Shaking hands with her brother.
Shaking hands with Meghna!

Yes!

This is just the opposite to what we previously got. In order to shake hands with me, you have go down the heirarchy.

Exactly what we call capturing. ie. Executing the outermost div first and then propagating inside.

Note: According to W3C standards, event capturing occurs followed by event bubbling.

Now, let’s prove this statement by using a combination of true and false values as the third argument for addEventListener() method.

Mix And Match


Cosider the following:

dad.addEventListener(
  "click",

  () => {
    console.log("Shaking hands with her dad.")
  },
  true // Capturing
)
mum.addEventListener(
  "click",
  () => {
    console.log("Shaking hands with her mum.")
  },
  false // Bubbling
)
bro.addEventListener(
  "click",
  () => {
    console.log("Shaking hands with her brother.")
  },
  true // Capturing
)

meg.addEventListener(
  "click",
  () => {
    console.log("Shaking hands with Meghna!")
  },
  false // Bubbling
)

Can you guess what will happen on clicking the innermost div ?

Yes! It’s :

Shaking hands with her dad.
Shaking hands with her brother.
Shaking hands with Meghna!
Shaking hands with her mum.

First, we went down the heirarchy of divs logging values on true instances of the capture event.

Then, we bubbled up from the bottom-most div to the topmost div. But this time, logging values for false instaces of the capture event. Hence the output.

Stopping Propagation


stop

We may even stop the further propagation of events by using .stopPropagation() method as follows:

dad.addEventListener(
  "click",

  e => {
    console.log("Shaking hands with her dad.")
    e.stopPropagation()
  },
  true // Capturing
)
mum.addEventListener(
  "click",
  () => {
    console.log("Shaking hands with her mum.")
  },
  false // Bubbling
)
bro.addEventListener(
  "click",
  () => {
    console.log("Shaking hands with her brother.")
  },
  true // Capturing
)

meg.addEventListener(
  "click",
  () => {
    console.log("Shaking hands with Meghna!")
  },
  false // Bubbling
)

// Output on clicking the innermost div:
// Shaking hands with her dad.

Here, you could shake hands with just my dad!

Poor!

This happened so because the stopPropagation() method was defined for the instance of capture event.

I encurage you to try placing stopPropagation() method for different instances of true and false values for the capture event to understand better.

The Mystery Of Bungee Jumping


Have you ever experienced bungee jumping ?

I haven’t as yet, still, trying to set an example ;-)

Bungee

So, how is that related to event capturing and bubbling ?

See, in bungee jumping, we take a leap from the station to as low as we can (so long as we dont die), and then we are brought back up.

Right ?

Similarly, as per W3C standards, event capturing occurs followed by event bubbling.That means, diving from top to bottom is like performing capturing and coming up from bottom to top like bubbling.

You might have found this example to be a lame one, but believe me, you’re not gonna forget the order (capturing first and then bubbling) henceforth.

Final Thoughts…


Now, we know that when an event is trigerred, event propagation forms a cycle performing functions meant for capturing event first and bubbling thereafter.

And, we may stop further propagation of events too using .stopPropagation() method.

If you’ve heard of event trickling, don’t worry, it is just the other name for event capturing and hence, can be interchangeably used.

In the end, bungee jumping won’t let us forget about trickling down and then bubbling up ;)