Removing an anonymous event listener

38,015

Solution 1

There is no way to cleanly remove an event handler unless you stored a reference to the event handler at creation.

I will generally add these to the main object on that page, then you can iterate and cleanly dispose of them when done with that object.

Solution 2

You could remove the event listener like this:

element.addEventListener("click", function clicked() {
    element.removeEventListener("click", clicked, false);
}, false);

Solution 3

Old Question, but here is a solution.

Strictly speaking you can’t remove an anonymous event listener unless you store a reference to the function. Since the goal of using an anonymous function is presumably not to create a new variable, you could instead store the reference in the element itself:

element.addEventListener('click',element.fn=function fn() {
    //  Event Code
}, false);

Later, when you want to remove it, you can do the following:

element.removeEventListener('click',element.fn, false);

Remember, the third parameter (false) must have the same value as for adding the Event Listener.

However, the question itself begs another: why?

There are two reasons to use .addEventListener() rather than the simpler .onsomething() method:

First, it allows multiple event listeners to be added. This becomes a problem when it comes to removing them selectively: you will probably end up naming them. If you want to remove them all, then @tidy-giant’s outerHTML solution is excellent.

Second, you do have the option of choosing to capture rather than bubble the event.

If neither reason is important, you may well decide to use the simpler onsomething method.

Solution 4

You may try to overwrite element.addEventListener and do whatever you want.
Something like:

var orig = element.addEventListener;

element.addEventListener = function (type, listener) {
    if (/dontwant/.test(listener.toSource())) { // listener has something i dont want
        // do nothing
    } else {
        orig.apply(this, Array.prototype.slice.apply(arguments));
    }
};

ps.: it is not recommended, but it will do the trick (haven't tested it)

Solution 5

Assigning event handlers with literal functions is tricky- not only is there no way to remove them, without cloning the node and replacing it with the clone- you also can inadvertantly assign the same handler multiple times, which can't happen if you use a reference to a handler. Two functions are always treated as two different objects, even if they are character identical.

Share:
38,015
erikvold
Author by

erikvold

Updated on July 08, 2022

Comments

  • erikvold
    erikvold almost 2 years

    Is there anyway to remove an event listener added like this:

    element.addEventListener(event, function(){/* do work here */}, false);
    

    Without replacing the element?

  • erikvold
    erikvold almost 14 years
    "You can't" in summary? which is what I think is the correct answer.
  • kennebec
    kennebec almost 14 years
    You can, if you assign them as properties, and not using addEventListener. element.onmouseover=function(){dothis}; element.onmouseover='';
  • Brock Adams
    Brock Adams almost 14 years
    In Greasemonkey applications, we don't have any control over how events are created in the base page. FYI, in a GM script, something like element.onmouseover=function won't work anyway, because of sandbox protection. See commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/… .
  • Brock Adams
    Brock Adams almost 14 years
    That only works if you are adding the event listener in the first place -- that you can modify the original listener() code. Since this is a Greasemonkey application, that is not possible. Even if the base-page script was changed, you'd only be adding another anonymous listener.
  • icktoofay
    icktoofay almost 14 years
    @Brock: Oh, I thought the intention was to remove a listener you added. I don't know of any way to remove a listener you didn't add and have no reference to the function of.
  • erikvold
    erikvold almost 14 years
    Brock is correct, this is a question for user scripting, but good answer none the less, I gave it an up vote!
  • merours
    merours about 9 years
    You may want to add that callee is deprecated since ES5 (see mdn or SO )
  • icktoofay
    icktoofay about 9 years
    @fxm: Thanks. I don’t remember why I originally used arguments.callee and a named function expression ought to work fine, so I edited my answer.
  • Lorcan O'Neill
    Lorcan O'Neill over 8 years
    Alternatively you can replace EventTarget.prototype.addEventListener. This worked for me
  • Matthew Read
    Matthew Read over 7 years
    You've violated the constraints of the question.
  • Michael
    Michael over 6 years
    i wonder why addeventlistener doesn't return such a reference for future use by removeeventlistener...
  • Joe
    Joe almost 6 years
    It does, this is what you save.
  • Manngo
    Manngo almost 6 years
    Back to the question, jQuery actually stores a reference to the function and then adds the function. This is why you don’t need to specify which function you are removing. That is, it’s not anonymous by the time it is added. BTW, jQuery prefers .off() to .unbind().
  • BairDev
    BairDev over 5 years
    @Joe and for users coming late here: addEventListener returns undefined at least in some cases. For example in a BroadcastChannel context.
  • Jarrod McGuire
    Jarrod McGuire over 5 years
    Like this solution am going to use it. Can't think if it matters or not, but there will still be a reference to the function afterward e.g. calling element.fn() will still return the result of the function. Could this be a memory issue if not cleaned up?
  • Jason Gross
    Jason Gross over 5 years
    Note that, as per stackoverflow.com/a/27107765/377022, in Chrome console, you can use the getEventListeners function
  • Joe
    Joe over 5 years
    @JasonGross Yes, the APIs have much improved since WebKit in 2010 when I created this answer.
  • Jason Gross
    Jason Gross over 5 years
    @Joe Sure. It might be nice to update the officially-accepted answer so that people who come looking to this as a reference in the future (as I did) are aware of the new developments.
  • Joe
    Joe over 5 years
    I haven't done extensive JavaScript development in 5 years or so. I'm happy for someone to edit it to be correct. I'm more back end and embedded work now and not current in modern JavaScript anymore. Although that link mentions that this is only available in console and the request was for doing it progromatically. I don't know if this has changed at all.
  • ortonomy
    ortonomy almost 3 years
    why give a jquery answer for a JS question?
  • shen
    shen about 2 years
    Is clicked function visible within itself? I have some problems with this: stackoverflow.com/questions/70991363/…
  • Bravo
    Bravo about 2 years
    Only chrome supports this on the command line - it's abandoned