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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12012882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 11:12:02  来源:igfitidea点击:

How to remove all event handlers for child elements of a parent element using JQuery

jquery

提问by MindWire

Given a specific parent node, for example a dynamically created modal div. After adding a bunch of dynamic html to it and then binding those elements to click, mouseover, etc events, is there a way to un-bind all of the events associated with child elements of the modal div. In my specific example, once the modal div is hidden it is then removed from the dom entirely and then recreated from scratch each time it is needed.

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

I am looking for a way to not have to track all of the specific bindings, but rather just use one call to say: get any children elements that have bindings and 'off' them.

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

Note: I can validate that removing the element from the dom and then recreating it does not kill the binding as opening and closing the modal div causes the bound events to be fired the same number of times the div was created. I am using $(document).on('click', '#abc',function(e) {});to bind elements.

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

回答by Adil

You can use unbind()if you used bind()to attach the events.

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

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

or

或者

Use off()if you used on()to bind events.

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

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

For removing the event from all descendants instead of direct children you can use Descendant Selector (“ancestor descendant”).

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

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

回答by Utkanos

Yeap - use off()with no params - that will unbind all events bound.

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

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

If you meant literally children, i.e. not children OR descendants, use #parent > *instead.

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

回答by Lorenzo Meriggi

I also wondered if I needed to manually unbind every children of the removed element.

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

From jquery documentation you shouldn't:

从 jquery 文档你不应该:

jquery docs for remove

用于删除的 jquery 文档

If we had any number of nested elements inside , they would be removed, too. Other jQuery constructs such as data or event handlers are erased as well.

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

Since I was curious if this was true I checked the source code:

由于我很好奇这是否属实,我检查了源代码:

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;
}

as you can see:

如你看到的:

jQuery.cleanData( getAll( node ) );

is cleaning all the events of all the childrens of the removed element.

正在清理被移除元素的所有子元素的所有事件。

So in the end: if you use $(element).remove()or .empty(), you are already memory leak safe!

所以最后:如果你使用$(element).remove()or .empty(),你已经是内存泄漏安全的!

回答by Erick Maynard

There are some cases where you don't want to bind an event directly to an element. Rather, you want to bind it to a parent element, like "body" for example. This is essential when you want to define your event listeners globally but the element may not exist yet:

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

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

The problem here is if you try to run .off() on ".hover-item" it doesn't work. Alternatively, if you try to use .off() on "body", using .children() as recommended in the accepted answer, it doesn't do anything either.

这里的问题是,如果您尝试在“.hover-item”上运行 .off() 它不起作用。或者,如果您尝试在“body”上使用 .off(),按照已接受的答案中的建议使用 .children(),它也不会执行任何操作。

Instead of using .off(), I believe it's best practice to bind your events to a particular class name, and when you want to disable those events, remove the class name:

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

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

Now that particular element won't have the event listener enabled anymore. However, since you technically defined the event listener on "body", if you need to enable the hover effect again at some later time, you can just use addClass(".hover-item") and everything will work just fine.

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

Now, this really only applies in cases where you have one animation for multiple items. Hover events are a good example of this. Instead of applying different hover events to different buttons for example, you can apply the same event to all buttons. But if you just want to disable hover events for one particular button, this is the way to go.

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