您如何解除特定命名空间中的所有jQuery事件的绑定?

时间:2011-02-07 15:29:13

标签: jquery events

jQuery中是否存在“全局”unbind函数,这样我就可以从给定的命名空间中删除所有绑定事件?例如:

// assume these are the events bound to different elements
$('#foo').bind('click.myNS', ...);
$('#bar').bind('keyup.myNS', ...);
$('#baz').bind('dblclick.myNS', ...);    

// magic occurs here...
$.magicalGlobalUnbindFunction('.myNS');

// ...and afterwards, the three binds from above are gone

我见过的所有非绑定示例都需要先选择一些元素。我想从技术上讲,你可以做$('*').unbind('.myNS'),但这似乎非常效率不高。

7 个答案:

答案 0 :(得分:13)

您可以将myNS作为类添加到要取消绑定事件的每个元素。

答案 1 :(得分:9)

你总是可以包装$ .fn.bind,然后缓存必要的引用:

(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);

答案 2 :(得分:9)

您需要使用jQuery的OnOff方法。使用文档作为选择器。

$(document).off('.myNS');

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

然后你的方法看起来像

$(document).on('click.myNS','#foo', fooClicked);
var fooClicked = function(e){
    var $this = $(e.target);
    // do stuff
}

答案 3 :(得分:4)

你真的在寻找一种神奇的全球功能,但是一如既往地用魔法,你只能在简单的情况下获得幻觉。

还有使用.live().delegate()的jQuery解决方案(只是live()的变体)。

使用$("body").delegate("#foo", "click.myNs", func)您还绑定事件并使用$("#body").undelegate(".myNs")解除绑定。我在这里使用“body”元素但是当然你可以使用任何元素,它是你需要绑定的所有元素的祖先。

它会让你的“解除绑定”工作更快,但同样会让你的事件反应变慢。

答案 4 :(得分:3)

你需要入侵jQuery内部,这是一个简单实现的工作演示:

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

主要工作是在常规的js循环中完成的,并且不应该非常低效,因为即使这个页面最终只包含106个要循环的项目。您当然应该尽可能使用事件委托来保持jQuery处理程序集合中的项目数量尽可能小。

答案 5 :(得分:0)

您应该在绑定函数

中添加一个类
$('#foo').bind('click.myNS', ...).addClass('removeLater');
$('#bar').bind('keyup.myNS', ...).addClass('removeLater');
$('#baz').bind('dblclick.myNS', ...).addClass('removeLater');  

之后

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

如果#foo #bar#etc都是相同的元素或一小部分,您也可以这样做:

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

但是如果你有一个绑定事件,你不想删除那不是一个好主意

答案 6 :(得分:0)

您可以覆盖jquery的绑定方法,然后在覆盖存储中存储所有命名空间的引用和关联数组中的相应事件,然后根据要取消绑定的命名空间事件访问数组。代码可能是这样的

var eventArray=[];
(function ($) {
    var bind = $.fn.bind;
    $.fn.bind= function () {
    var result = bind.apply(this, arguments);
    var selector=arguments[0];
    var nameSpace= selector.split(".")[1];   //code to select the nameSpace eg. click.myNS o/p->myNS (update this if your selector has multiple '.')
    if(!eventArray[nameSpace])    //if the associative array does not contain the namespace yet
    {
       eventArray[nameSpace]=[];
    }
    eventArray[nameSpace].push(selector);
    return result;
};
})(jQuery);

现在使用eventArray,您可以根据需要解除绑定。取消绑定命名空间myNS上的所有事件的代码将如下所示:

$.each(eventArray['myNS'],function(){
   $(this).unbind();
});

希望这是一个很好的解决方案。如果我犯了任何错误,请告诉我。