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?

7
  • Should you attach your second event listener to the same 'test' element? Commented Oct 21, 2015 at 14:43
  • Can you post the relevant markup as well? Commented Oct 21, 2015 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 :) Commented Oct 21, 2015 at 14:49
  • 1
    It's due to event bubbling: stackoverflow.com/questions/4616694/… (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) Commented Oct 21, 2015 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! Commented Oct 21, 2015 at 15:15

2 Answers 2

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>

Sign up to request clarification or add additional context in comments.

6 Comments

Ah I didn't know there was another propagation stopping event. This looks like the answer I was hoping for. I will wait a while and see if anything else comes up before accepting it though. Thank you!
@AlexanderWeihmayer See updated post; included jQuery approach using .one()
Good addition. JQuery certainly makes life easier, but there's just something cool about DIYs :)
@AlexanderWeihmayer Updated pure js solution ; second now called at second click of #test
Thank you, the answers you have given seem very straight forward and efficient and I will accept it.
|
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.");
    });
  }
}

5 Comments

@valepu You can also use a function property: clickHandler. clickcount .
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.
my bad, didn't notice the eventlistener target, but i can solve that
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 :)
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, <div> with another eventhandler attached to it, it won't fire

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.