Home > Software design >  Event not Bubbling with addEventLsitener?
Event not Bubbling with addEventLsitener?

Time:10-26

I think I have a conceptual error in my understanding of event bubbling in Javascript.

addGlobalEventListener("click", ".green", (e) => {
  console.log("clicked green");
});


function addGlobalEventListener(type, selector, callback) {
  document.addEventListener(type, (e) => {
    if (e.target.matches(selector)) {
      callback(e);
    }
  });
}
.red {
  width: 50px;
  height: 50px;
  background-color: red
}

.green {
  width: 150px;
  height: 150px;
  background-color: green
}

.blue {
  width: 300px;
  height: 300px;
  background-color: blue
}
<div >
  <div >
    <div >
    </div>
  </div>
</div>

My understanding is if user clicks the box with class .red then event bubbles up through parents (red, green, blue, then document). I would think that this code should print "clicked green" if the user clicks on the red box OR the green box, but not the blue box. However, it only works if user clicks the green box. How can I alter the code such that "click green" is logged to the console when user clicks the div with OR ? Thank you!

CodePudding user response:

Event bubbling doesn't mean that the listener is called repeatedly. It just means that the event is triggered when you click anywhere in the element that the listener is attached to, but e.target will be the element that you actually clicked on.

Instead of using e.target.matches(), use e.target.closest() to detect if the clicked element is within the element you want to delegate to.

addGlobalEventListener("click", ".green", (e) => {
  console.log("clicked green");
});

function addGlobalEventListener(type, selector, callback) {
  document.addEventListener(type, (e) => {
    if (e.target.closest(selector)) {
      callback(e);
    }
  });
}
.red {
  width: 50px;
  height: 50px;
  background-color: red
}

.green {
  width: 150px;
  height: 150px;
  background-color: green
}

.blue {
  width: 300px;
  height: 300px;
  background-color: blue
}
<div >
  <div >
    <div >
    </div>
  </div>
</div>

  • Related