如何使用JQuery删除父元素的子元素的所有事件处理程序

时间:2012-08-17 20:40:27

标签: jquery

给定特定的父节点,例如动态创建的模态div。在向它添加一堆动态html然后将这些元素绑定到click,mouseover等事件后,有没有办法解除与模态div的子元素相关联的所有事件。在我的具体示例中,一旦隐藏了模态div,它就会从dom中完全删除,然后在每次需要时从头开始重新创建。

我正在寻找一种不必跟踪所有特定绑定的方法,而只是使用一个调用来说:获取任何具有绑定和“关闭”它们的子元素。

注意:我可以验证从dom中删除元素然后重新创建它不会终止绑定,因为打开和关闭模式div会导致绑定事件的触​​发次数与创建div的次数相同。我正在使用$(document).on('click', '#abc',function(e) {});来绑定元素。

4 个答案:

答案 0 :(得分:20)

如果您使用bind()附加活动,则可以使用unbind()

  $('#foo').children().unbind();
  $('#foo').children('.class').unbind(); //You can give selector for limiting clildren

如果您使用on()绑定事件,请使用off()

 $('#foo').children().off();
 $('#foo').children('class').off();   //You can give selector for limiting clildren

答案 1 :(得分:15)

Yeap - 使用没有参数的off() - 将解除绑定的所有事件。

$('#parent *').off();

如果您的字面意思是儿童,即不是儿童或后代,请改用#parent > *

答案 2 :(得分:4)

我还想知道是否需要手动取消绑定已删除元素的每个子节点。

从jquery文档中你不应该:

jquery docs for remove

  

如果我们内部有任意数量的嵌套元素,它们也会被删除。其他jQuery构造(如数据或事件处理程序)也会被删除。

因为我很好奇,如果这是真的,我检查了源代码:

function remove( elem, selector, keepData ) {
    var node,
        nodes = selector ? jQuery.filter( selector, elem ) : elem,
        i = 0;

    for ( ; ( node = nodes[ i ] ) != null; i++ ) {
        if ( !keepData && node.nodeType === 1 ) {
            jQuery.cleanData( getAll( node ) );
        }

        if ( node.parentNode ) {
            if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
                setGlobalEval( getAll( node, "script" ) );
            }
            node.parentNode.removeChild( node );
        }
    }

    return elem;
}

你可以看到:

jQuery.cleanData( getAll( node ) );

正在清除已移除元素的所有子项的所有事件。

所以最后:如果你使用$(element).remove().empty(),那么你已经安全了!

答案 3 :(得分:1)

在某些情况下,您不希望将事件直接绑定到元素。相反,您希望将其绑定到父元素,例如“body”。当您想要全局定义事件侦听器但该元素可能尚不存在时,这是必不可少的:

$("body").on("mouseenter", ".hover-item", function() {
    // do the thing
}

这里的问题是如果你试图在“.hover-item”上运行.off()它就不起作用了。或者,如果你尝试在“body”上使用.off(),使用接受答案中建议的.children(),它也不会做任何事情。

我认为最好将事件绑定到特定的类名,而不是使用.off(),当您想要禁用这些事件时,请删除类名:

$(".the-element").removeClass(".hover-item");

现在该特定元素将不再启用事件侦听器。但是,由于您在技术上定义了“body”上的事件侦听器,如果您需要稍后再次启用悬停效果,您可以使用addClass(“。hover-item”),一切都会正常工作。

现在,这实际上仅适用于多个项目有一个动画的情况。悬停事件就是一个很好的例子。例如,您可以将相同的事件应用于所有按钮,而不是将不同的悬停事件应用于不同的按钮。但是,如果您只想为一个特定按钮禁用悬停事件,则可以采用此方法。