0

When I attach a click handler inside the procedure of another click handler, the same event immediately triggers the newly defined handler. How to prevent this?

<input onclick="document.body.addEventListener('click',function(){
  document.body.removeEventListener('click',this);alert('test');})">
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
aelgoa
  • 1,193
  • 1
  • 8
  • 24
  • 1
    the second argument to removeEventListener is the listener function to remove. should be `addEventListener('click', function listener(){ this.removeEventListener('click',listener);})` – levi Oct 23 '14 at 13:50
  • I didn't know it was possible to name anonymous functions in js lol tx – aelgoa Oct 23 '14 at 14:24
  • Actually, you cannot name anonymous functions. If you name them, they are no longer anonymous. I guess you meant to say naming a function expression. –  Oct 23 '14 at 15:34
  • IT's all rather eponymous, because a function expression is syntactic sugar for a lambda being assigned to a variable inline. you might just as well say the function expression creates an anonymous function, and the identifier used in its declaration is a language construct to create a named reference to that function – aelgoa Oct 23 '14 at 18:32

1 Answers1

1

Wrap up your add within a setTimeout with a timeout of 0. This will move your block of code to the bottom of the execution queue and allow everything else to happen first, including the resolution of anything else to do with the initial click:

function attachHandler() {
    setTimeout(function() { 
        document.body.addEventListener('click',function listener() {
            this.removeEventListener('click', listener);
            alert('test');
        })
    }, 0});
}

<input onclick="attachHandler()" />
aelgoa
  • 1,193
  • 1
  • 8
  • 24
James Thorpe
  • 31,411
  • 5
  • 72
  • 93
  • I'm using this solution, but I don't really like the overhead of creating another function wrapper, a timer, tweaking execution order.... – aelgoa Oct 23 '14 at 18:39
  • @aelgoa you don't necessarily need the `attachHandler` function, the `setTimeout` could have gone directly in the `onclick` handler - I just added it for clarity. You say you don't really like tweaking the execution order, but not doing so is precisely what's causing the issue. Using `setTimeout(f, 0);` is a [pretty widely used method](http://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful) for doing so - you'll find many instances of it – James Thorpe Oct 23 '14 at 18:48
  • I was refferring to the setTimeOut callback itself instead of the handler you added to make things clear. nesting 2 or 3 levels of functions just to bind an event is just awful imo. I think browser design should provide the ability to control the event order more directly. but maybe they have and I havn't read it anywhere and no one has wrote it here yet – aelgoa Oct 23 '14 at 18:59