0

I have the following html and with event bubbling it makes perfect sense to me how it works. It bubbles up, so clicking on three would give me three, two, one. Clicking on two, would give me two and one.

However with capture: true, when I click on three it works as I feel it should, it goes down from one to three. What I don't understand is when I click on one or two, why does it not capture down. If I click on one, it should capture down and give me one, two, three. If I click on two, it should give me two, three.

const divs = document.querySelectorAll('div');

function logText(e) {
  console.log(this.classList.value);

}
divs.forEach(div => div.addEventListener('click', logText, {
  capture: true
}));
<div class="one">
one
  <div class="two">
  two
    <div class="three">
    three
    </div>
  </div>
</div>
Cid
  • 14,968
  • 4
  • 30
  • 45
Alana
  • 13
  • 1
  • It captures down from the top to the target, then bubbles up from the target to the top. The target is the one you click on; events don’t capture down into unrelated elements. Is that what you’re asking? – Ry- Jul 09 '20 at 07:26
  • https://stackoverflow.com/questions/4616694/what-is-event-bubbling-and-capturing – Ry- Jul 09 '20 at 07:28
  • with capture set to true, if I click on two, should it not go from the top ( top being one) to two which is the target? – Alana Jul 09 '20 at 07:33
  • 1
    Correct! That’s what I see when clicking on two. Do you get something else? – Ry- Jul 09 '20 at 07:34
  • 1
    Thank you so much, I understand now. I thought the one in the console was related to when I clicked on one, but it was from when I clicked on two. Even though it puts a 2 before it. Thanks again – Alana Jul 09 '20 at 07:39

2 Answers2

0

Then the event moves down from the topest document to the event.target, calling handlers assigned with addEventListener(..., true) on the way,

In your case, on clicking on one, you are just clicking on one, there is nothing before it, one is the topest element. but when you click on three, there is one and two on top of, so it comes down from one > two > three.

const divs = document.querySelectorAll('div');

function logText(e) {
  console.log(this.classList.value);
}

divs.forEach(div => div.addEventListener('click', logText, true));
div {
  display: flex;
  justify-content: center;
  align-items: center;
}

.one {
  width: 600px;
  height: 600px;
  background: red
}

.two {
  width: 400px;
  height: 400px;
  background: blue
}

.three {
  width: 200px;
  height: 200px;
  background: green
}
<div class="one">
  <div class="two">
    <div class="three"></div>
  </div>
</div>
Marik Ishtar
  • 2,899
  • 1
  • 13
  • 27
0

In your case, you can achieve this by bubbling. See the example.

<!DOCTYPE HTML>
<html>

<head>
</head>

<body>

    <div class="one">
        one
        <div class="two">
            two
            <div class="three">
                three
            </div>
        </div>
    </div>

    <script>

        for (let elem of document.querySelectorAll('div')) {
            elem.addEventListener("click", e => {
                console.log(`Bubbling: \n${elem.innerText}`);
                e.stopPropagation();
            });
        }
    </script>

</body>

</html>

Now understand about the capturing and bubbling here:

<!DOCTYPE HTML>
<html>

<head>
</head>

<body>

    <div class="one">
        one
        <div class="two">
            two
            <div class="three">
                three
            </div>
        </div>
    </div>

    <script>

        for (let elem of document.querySelectorAll('div')) {

            elem.addEventListener("click", e => {
                console.log(`Capturing: \n${elem.innerText}`);
            }, true);

            elem.addEventListener("click", e => {
                console.log(`Bubbling: \n${elem.innerText}`);
            });
            
        }
    </script>

</body>

</html>

If you click on three, then the sequence is:

1. one → two → three (capturing phase, the first listener).

2. three → two → one (bubbling phase, the second listener).

That's why you can achieve your expected result by stopping the bubbling phase with e.stopPropagation(); this event inside the bubbling listener.

NOTE: Bubbling is convenient. Don’t stop bubbling without a need!

Shahnawaz Hossan
  • 2,695
  • 2
  • 13
  • 24