How would you unbind all jQuery events from a particular namespace?

前端 未结 7 1287
半阙折子戏
半阙折子戏 2021-02-06 22:50

Is there a \"global\" unbind function in jQuery, such that I\'d be able to remove all bound events from a given namespace? eg:

// assume these are the events bou         


        
相关标签:
7条回答
  • 2021-02-06 23:04

    You should add a class within the bind function

    $('#foo').bind('click.myNS', ...).addClass('removeLater');
    $('#bar').bind('keyup.myNS', ...).addClass('removeLater');
    $('#baz').bind('dblclick.myNS', ...).addClass('removeLater');  
    

    and afterwards

    $('.removeLater').unbind();
    

    If #foo #bar and #etc are all the same element or small set of them, you could also do:

    $('div, button').unbind();
    

    but if you have a bound event you don't want to remove that wouldn't be a good idea

    0 讨论(0)
  • 2021-02-06 23:21

    You need to use jQuery's On and Off methods. Use document as the selector.

    $(document).off('.myNS');
    
    $(document).on('click.myNS','#foo', ...);
    $(document).on('keyup.myNS','#bar', ...);
    $(document).on('dblclick.myNS','#baz',''');
    

    then your methods could look like

    $(document).on('click.myNS','#foo', fooClicked);
    var fooClicked = function(e){
        var $this = $(e.target);
        // do stuff
    }
    
    0 讨论(0)
  • 2021-02-06 23:23

    You need to hack into jQuery internals, here's a working demo of a simple implementation:

    http://jsfiddle.net/nkMQv/1/

    The main work is done in regular js loops and shouldn't be very inefficient as even this page contains ultimately only 106 items to loop through. You should of course use event delegation as much as possible to keep the amount of items in the jQuery handler collection as small as possible.

    0 讨论(0)
  • 2021-02-06 23:27

    You could always wrap $.fn.bind and then cache the necessary refs:

    (function ($) {
        var origBind = $.fn.bind,
            boundHash = {};
    
        $.fn.bind = function (type, data, fn) {
            var namespace = '',
                events = [];
    
            if (typeof type === 'string') {
                // @todo check the allowed chars for event namespaces.
                namespace = type.replace(/^[^.]+/, '');
    
                if (namespace.length) {
                    events = boundHash[namespace];
    
                    // Namespaces can hold any number of events.
                    events = boundHash[namespace] = $.isArray(events) ? events : [];
    
                    // Only really need ref to the html element(s)    
                    events.push({
                        type: type, 
                        fn: $.isFunction(fn) ? fn : data, 
                        that: this.length > 1 ? this.toArray() : this[0]
                    });
                }
            }
    
            origBind.apply(this, arguments);
        };
    
        // namespace to be muffled. Feel free to qualify a specific event type.
        $.muffle = function (namespace, type) {
            var events = [];
    
            if (boundHash.hasOwnProperty(namespace)) {
                events = boundHash[namespace];
    
                $.map(events, function (event) {
                    var _type = type || event.type;
    
                    if (event.type.indexOf(_type) === 0) {
                        $(event.that).unbind(_type, event.fn);
                    }
                });
    
                // @todo think of better return value.
                return true;
            }
    
            // @todo think of better return value.
            return false
        };
    })(jQuery);
    
    0 讨论(0)
  • 2021-02-06 23:28

    You could add myNS as a class to each of the elements where you want to unbind the events.

    0 讨论(0)
  • 2021-02-06 23:31

    Truly you are looking for a magical global function but as always with magic you can only get illusion, in this case, of simplicity.

    There is also jQuery solution using .live() or .delegate() (which is only variant of live()).

    Using $("body").delegate("#foo", "click.myNs", func) you also bind event and using $("#body").undelegate(".myNs") you unbind it. I use here "body" element but ofcourse you can use any element that is ancestor of all elements you need binding on.

    It will make your "unbinding" work faster but again it will make your events respond slower.

    0 讨论(0)
提交回复
热议问题