13

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

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

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

4

4 回答 4

22

如果您曾经附加事件,则可以使用unbind() 。bind()

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

或者

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

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

要从所有后代而不是直接子代中删除事件,您可以使用Descendant Selector (“ancestor descendant”)

$('#foo *').off(); 
于 2012-08-17T20:43:27.640 回答
18

是的 -off()不带参数使用 - 这将取消绑定所有事件。

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

如果您的意思是字面上的孩子,即不是孩子或后代,请#parent > *改用。

于 2012-08-17T20:42:26.147 回答
5

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

从 jquery 文档中你不应该:

用于删除的 jquery 文档

如果我们在里面有任意数量的嵌套元素,它们也会被删除。其他 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()or .empty(),你已经是内存泄漏安全的了!

于 2016-02-12T15:28:13.610 回答
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") 一切都会正常工作。

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

于 2016-06-06T06:04:58.430 回答