0

I want to define an EventListener after clicking on a button.

I set EventListener in another EventListener and want the child EventListener to be listening to click event only after the parent event was triggered.

Code snippet:

const btn = document.querySelector(".btn")
btn.onclick = function() {
  console.log("PARENT")
  document.onclick = function() {
    console.log("CHILD")
  }
}
<button class="btn">Click</button>

Current behavior:

Parent and child events trigger together, even on the first click on the button.

So, even on the first click on the button I see "PARENT" "CHILD" in console, but I want to see only "PARENT".

Desired behavior:

Child EventListener should be listening to click event only after clicking on the button element. Thus, I want to see on the first click on the button only "PARENT" in console and after on subsequent clicks: "PARENT" "CHILD".

Why it works in such way? Why does the event, defined in child EventListener, trigger with the event, defined in parent EventListener, though child EventListener should only start listening to click event when the parent event is triggered?

MichaelLearner
  • 429
  • 4
  • 14
  • 1
    Look into "event bubbling". First the btn event handler is executed and the document click handler is registered. **Then the event travels UP the dom** until the document is reached. There it will trigger your document onclick handler which has already been registered at this point. – Đinh Carabus Jan 11 '23 at 16:48

2 Answers2

1

The event is handled for the button - where the new listener is assigned, then it bubbles up and handles the newly registered handler.

Anyway, it may be easier and more clear to use event delegation and a data-attribute to save the click state of the button. for example:

document.addEventListener(`click`, handle);

function handle(evt) {
  console.clear();
  if (evt.target.classList.contains(`btn`)) {
    evt.target.dataset.clicked = 1;
    return console.log(`.btn clicked`);
  }
  
  if (evt.target === document.documentElement) {
    if (!document.querySelector(`.btn`).dataset.clicked) {
      return true;
    }
     
    return console.log(`document clicked`);
  }
}
<button class="btn">Click</button>
KooiInc
  • 119,216
  • 31
  • 141
  • 177
0

const btn = document.querySelector(".btn")
btn.onclick = function() {
  console.log("PARENT");
  setTimeout(() => (
    document.onclick = function() {
      console.log("CHILD")
    }
  ), 0);      
}
<button class="btn">Click</button>

more content: Why is setTimeout(fn, 0) sometimes useful?

ErickJFZ
  • 1
  • 1