3

I have two div elements, inner and outer. I am triggering click event on inner div programmatically only once. But the log shows that the event handler is invoked twice on inner div. Here is the code. Can you please help understand why is this happening. Code is also hosted on codesandbox

const inner = document.querySelector(".inner");
const outer = document.querySelector(".outer");
    
function clk(event) {
  console.log("click");
  console.log(event.target);
}
    
inner.addEventListener("click", clk);
outer.addEventListener("click", clk);
    
inner.click();
<div class="outer" id="div1">
  <div class="inner" id="div2"></div>
</div>
David
  • 208,112
  • 36
  • 198
  • 279
A Singh
  • 107
  • 7
  • 2
    Just like the answers state, it's due to event bubbling. If you want to prevent that from happening you can use `event.stopPropagation()`. – Sebastian Gbudje Apr 15 '22 at 14:42
  • note also that if you logged `event.currentTarget` instead of `event.target1, you'd see the "outer" div for the second log - `currentTarget` is always the element the event handler was added to, while `target` is the actual element that the event was triggered on originally. – Robin Zigmond Apr 15 '22 at 14:51

4 Answers4

4

add

event.stopPropagation()

to your clk function

DCR
  • 14,737
  • 12
  • 52
  • 115
3

This is because of Event bubbling.

What's happening is :

  1. You tigger the click event on inner.
  2. The event listener of inner is called.
  3. The click event bubbles up to outer.
  4. The event listener of outer is called

The target is inner in both calls to the clk function, because it's a property of the initial event. It doesn't depend on the element the listener is registered on.

Araelath
  • 575
  • 2
  • 15
1

It happens because you subscribe on outer as well as on inner because of event bubbling effect which is presented in JavaScript(see: https://javascript.info/bubbling-and-capturing). That`s why it is executed on inner and outer element - you added handler for both:

inner.addEventListener("click", clk);
outer.addEventListener("click", clk);
Mykyta Halchenko
  • 720
  • 1
  • 3
  • 21
1

The event is only triggered once per element. You can see this if you use the currentTarget rather than the target

function clk(event) {
  console.log("click");
  console.log(event.currentTarget);
}
Blake Plumb
  • 6,779
  • 3
  • 33
  • 54