2

I'm using JQuery on method to attach an event handler to the window object:

$(window).on('resize', function(e){
     /** my functional code goes here **/
     e.stopPropagation();
});

This is event handler is being called multiple times: The reason this is so is because the event handler is in the initialization section of a JQuery plugin, so when someone calls the plugin constructor like so:

$('selector').myPlugin({settings_1});
$('selector').myPlugin({settings_2});
$('selector').myPlugin({settings_3});

The event handler gets attached 3 times.

I'm looking for a way to identify and decommission all but one of the 3 event handlers (using off method) so that during a resize, only one of them will get triggered.

How do I identify the event handlers and remove the ones I want?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
ObiHill
  • 11,448
  • 20
  • 86
  • 135
  • 1
    Wouldn't it suffice to remove **all** `resize` listeners and then add a new one? – MCL Feb 13 '13 at 17:43
  • 1
    @MCL Right, why wouldn't $(window).off("resize") be the case? – Pat Burke Feb 13 '13 at 17:45
  • @MCL Unfortunately, I can't just remove them all because my functional code has a reference to the plugin instance (one for each of the three) that attached the event handler, so I'm not sure how I would reassign this reference after I do what you suggest? – ObiHill Feb 13 '13 at 17:56
  • @ChuckUgwuh In that case, it's a tough one. jQuery provides functionality to [retrieve attached event handlers with $._data()](http://stackoverflow.com/a/2518441/1282023), but it's meant for debugging purposes only. You could still give it a try and see how it works. Anyway, telling us the name of your plugin would certainly help. – MCL Feb 13 '13 at 17:59
  • @MCL It's a plugin I'm developing, hasn't been released yet. Thanks for the tips. I think I might have to use named event trigger definitions inside the plugin constructor, and then use a timed script that will run once to attach the handler that will reference the selected trigger. A hack but it just might work. – ObiHill Feb 13 '13 at 18:17
  • @ChuckUgwuh If you are able to change the plugin's source, it will be no problem at all and you don't need to mess around with experimental functions. Why don't you store all your handlers in a static/global variable and temporarily disable all but one? But frankly, this sounds like a poor design to me... – MCL Feb 13 '13 at 18:22

3 Answers3

0

Try this:

function myHandler(e){
     /** my functional code goes here **/
     e.stopPropagation();
}

$(window).on('resize', function (e){
    $(window).off('resize', myHandler);
    $(window).on('resize', myHandler);
});
Roman Goyenko
  • 6,965
  • 5
  • 48
  • 81
0

If your event handlers have been attached only with jquery (not with plain javascript), read the answer to this question to check if a DOM element already has an event handler and, in your case, avoid duplicating it.

Community
  • 1
  • 1
Roberto Linares
  • 2,215
  • 3
  • 23
  • 35
  • Thanks a lot. This was quite helpful, although the specific functionality in the answer has been removed in JQuery 1.8. I found an alternative way of doing this which I'll post as an answer shortly. – ObiHill Feb 18 '13 at 19:04
  • And, where is the answer? – dikirill Dec 13 '13 at 18:47
  • Sorry for the delay guys. I think I ended up using `$(window).off("resize")` with a timed interval function that reattached only the specific event handler I needed (i.e. 1, 2, or 3 depending on some factors in code). Fortunately, I did a redesign which obviated the need for the initial construct. In hindsight, probably not the best piece of software design. – ObiHill Oct 04 '14 at 01:20
0

You can leverage an array of {key, callback}. Something like this:

window.resizeCallbacks = [];

function addResizeCallback(key, callback) {
    window.resizeCallbacks.push({
        key: key,
        callback: callback
    });
}

function removeResizeCallback(key) {
    var index = -1;
    for (var i = 0; i < window.resizeCallbacks.length; i++) {
        if (window.resizeCallbacks[i].key === key) {
            index = i;
        }
    }
    if (index >= 0) {
        window.resizeCallbacks.splice(index, 1);
    }
}


$(function() {
    $(window).resize(function() {
        for (var i = 0; i < window.resizeCallbacks.length; i++) {
            window.resizeCallbacks[i].callback();
        }
    });
});
Dragos Rizescu
  • 3,380
  • 5
  • 31
  • 42