Javascript 追加元素并删除它会破坏jquery中的所有事件处理程序吗?

Javascript 追加元素并删除它会破坏jquery中的所有事件处理程序吗?,javascript,jquery,Javascript,Jquery,好的,我创建元素,分配click处理程序,并将其附加到body。然后我删除它并重新结束它,然后单击处理程序不再工作 为什么会发生这种情况 var btn = $('<button>').text('hi').click(function(){console.log(3);}); var div = $('<div>'); div.append(btn); $('body').append(div); //click it now, it works.. div.html(

好的,我创建元素,分配click处理程序,并将其附加到body。然后我删除它并重新结束它,然后单击处理程序不再工作

为什么会发生这种情况

var btn = $('<button>').text('hi').click(function(){console.log(3);});
var div = $('<div>');
div.append(btn);
$('body').append(div);
//click it now, it works..
div.html('');
div.append(btn);
// now button doesn't work..
var btn=$('').text('hi')。单击(函数(){console.log(3);});
var div=$('');
附加分区(btn);
$('body')。追加(div);
//现在点击它,它就工作了。。
div.html(“”);
附加分区(btn);
//现在按钮坏了。。
既然
.html(“”)
本质上与相同,那么以下内容适用于(从中):

为了避免内存泄漏,jQuery在删除元素本身之前从子元素中删除其他结构,如数据和事件处理程序

如果要删除元素而不销毁其数据或事件处理程序(以便以后可以重新添加),请改用
.detach()

一种选择是使用。这样做时,事件不会直接绑定到
按钮
元素,而是绑定到未删除的常量父元素


如上所述,另一个选项是使用,以便从DOM中删除元素,而不删除附加的事件侦听器

.remove()
相同,不同之处在于
.detach()
保留与已删除元素关联的所有jQuery数据。当删除的元素稍后要重新插入DOM时,此方法非常有用


将其放在第二个div.append(btn)之后;-><代码>btn=$('button')。文本('hi')。单击(函数(){console.log(3);})

发生这种情况是因为您在包含按钮的DIV上调用
html()

当您使用空字符串调用
html()
时,它会在内部调用
empty()

在元素上调用
empty()
将迭代该元素中的所有元素,从而安全地删除所有数据和事件

它通过调用按钮上的
jQuery.cleanData
来实现这一点,该按钮再次显式调用
jQuery.removeEvent
,删除按钮上的所有事件

该按钮仍然存储在变量
btn
中,因此可以再次追加,但由于父元素调用了
html(“”
,因此它已丢失所有数据和附加到它的所有事件

解决方案是使用
detach()
删除所有数据和事件都完好无损的元素,这样就可以再次追加该元素,或者可以将事件附加到未删除的父元素,或者只隐藏该元素,通常没有理由删除该元素只是为了重新添加它,最好隐藏它


这是一个非常有趣的情况。使用
html(“”)
方法清除
div
时会发生什么情况。看看,您将看到jQuery在内部调用
jQuery.cleanData(getAll(elem,false))。此方法负责删除已删除的所有子元素的所有相关
数据。这对于避免内存泄漏非常重要

清除数据还会删除与
(和类似)方法上的
绑定的事件,因为这些事件处理程序也存储在内部缓存对象中

因此,即使您删除了
div
的内容,
btn
对象仍在内存中,但以前绑定到它的事件已消失

这就是问题的解释。解决方案是使用名为的专用方法。它将从DOM中删除按钮,但将保留事件数据,以防稍后再次追加元素

// remove element but keep its data
btn.detach();

// append back
div.append(btn);

在这种情况下,您不应该使用
html(“”)

不知道确切情况,但可能是因为您没有关闭div标记。我从未见过像你这样的jQuery选择器have@TimotheusTriebl
不是选择器,它被jQuery用于创建相应的DOM元素。啊,很高兴知道:)谢谢,这更好:)很好的解释,我觉得这不是模块化的……基本上我一直在尝试学习设计模式,特别是MVC。。我还没有看到它的好处。我开始认为并不是所有的应用都能从中受益though@MuhammadUmer它到底是如何不模块化的呢?我指的是第一部分,但我想它很好。但是,对于多个项目,我必须创建一个函数来重新连接所有事件。但是,我想知道是否可以告诉jquery不要销毁所有事件。
div.find('button').detach();
div.append(btn);
// remove element but keep its data
btn.detach();

// append back
div.append(btn);