14

I am trying to add a click event to the document in another click event attached to a button. However, the second click event is fired right away as if the event overlaps. I looked into stopping propagation, using a timeout, removing the listener, preventDefault(), but I've had no success.

This is an example of what I am trying to do.

document.getElementById("test").addEventListener('click', first);

function first(){
    document.addEventListener('click', second);
}
function second(){
    alert("I'm not suppose to appear after the first click, only the second.");
}

For testing, I am using a simple button

<button type="button" id="test">Click</button>

I am doing this without JQuery. Is this possible?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Alexander Weihmayer
  • 366
  • 1
  • 3
  • 10
  • Should you attach your second event listener to the same 'test' element? – Olivier De Meulder Oct 21 '15 at 14:43
  • Can you post the relevant markup as well? – Hanlet Escaño Oct 21 '15 at 14:46
  • 1
    Olivier, no what I am trying to do needs to be attached to the whole document, no matter where you click it will trigger the next event. Hanlet, the markup is posted, it's very very simple :) – Alexander Weihmayer Oct 21 '15 at 14:49
  • The answers I have received seem to work, but can anyone explain to me what's going on and why exactly the second event is being triggered right away? I will accept an answer soon, just waiting to see if anything else comes around! Thank you all – Alexander Weihmayer Oct 21 '15 at 14:55
  • 1
    It's due to event bubbling: http://stackoverflow.com/questions/4616694/what-is-event-bubbling-and-capturing (events get forwared to the upper level) so this happens: 1) click event on button 2) you attach an eventlistener to the body 3) click event gets forwared to the body (which now has an eventlistener) – valepu Oct 21 '15 at 15:13
  • 1
    My gosh. Why was I so ignorant. Valuable piece of info, I was not aware of what bubbling was. Much appreciated! – Alexander Weihmayer Oct 21 '15 at 15:15
  • You are welcome, i wasn't aware of it until a week ago :) (or better, i knew this happened, i didn't know it was called event bubbling) – valepu Oct 21 '15 at 15:16

2 Answers2

18

Try using event.stopImmediatePropagation()

document.getElementById("test").addEventListener('click', first);

function first(e){
    e.stopImmediatePropagation();
    this.removeEventListener("click", first);
    document.onclick = second;
}
function second(){
    alert("I'm not suppose to appear after the first click, only the second.");
}
<button type="button" id="test">Click</button>
guest271314
  • 1
  • 15
  • 104
  • 177
2

You can use a variable that keeps count of the clicks done

document.getElementById("test").addEventListener('click', clickHandler);

var clickCount=0;
function clickHandler(event){
  clickCount++;
  if(clickCount==2){
    event.target.removeEventListener("click");
    document.addEventListener('click', function(){
      alert("I'm not suppose to appear after the first click, only the second.");
    });
  }
}

If you don't want to use a global variable you can use dataset, make a button with this:

<button type="button" id="test" data-clickcount="0">Click</button>

And use this code:

document.getElementById("test").addEventListener('click', clickHandler);

function clickHandler(event){
  event.target.dataset.clickcount++;
  if(event.target.dataset.clickcount==2){
    event.target.removeEventListener("click");
    document.addEventListener('click', function(){
      alert("I'm not suppose to appear after the first click, only the second.");
    });
  }
}
valepu
  • 3,136
  • 7
  • 36
  • 67
  • 1
    @valepu You can also use a function property: `clickHandler. clickcount `. – Vidul Oct 21 '15 at 14:56
  • Ohh more things I was unaware of. Thank you :) However, the way this is setup only triggers on the button itself whereas I want the second click to trigger on the entire document. – Alexander Weihmayer Oct 21 '15 at 15:04
  • my bad, didn't notice the eventlistener target, but i can solve that – valepu Oct 21 '15 at 15:05
  • 1
    Thank you for the solution, but guest271314's method is very straight forward. However I will definitely remember these tricks and I thank you for the info you've given me :) – Alexander Weihmayer Oct 21 '15 at 15:29
  • 1
    no worries! I don't question tastes, just glad i've been of help. Just be aware of that stopimmediatepropagation since it might interrupt other click events on upper levels (because of event bubbling) so if you put your button inside a, let's say,
    with another eventhandler attached to it, it won't fire
    – valepu Oct 21 '15 at 15:34