我遇到过这样的情况:div的html内容在某个时候被改变成其他内容,然后又被改回来。一些jquery用户界面控件行为不端。我把问题简化为下面的代码片段,它基本上显示了与按钮相关的事件处理程序不再触发。我假设这些内容在某个时候被垃圾收集,当它们消失的时候。所以我的问题是-
当DOM中缺少事件处理程序时,如何防止它们被垃圾收集?
我知道我可以重新分配click()
函数,但是由于我使用的是外部库(jquery ui),我不知道它对我的控件做了什么,我只希望它们的事件恢复到以前的样子。
<div id="container">
<p>This container has a button, which will forget its click()...</p>
<input id="testbutton" type="button" value="Click Me!"/>
</div>
<script type="text/javascript">
$(function(){
$("#testbutton").click(
function(){
alert("Button has been clicked!");
})
});
</script>
<div>
<p>... when this button reseats html</p>
<input id="actionbutton" type="button" value="Toggle"/>
</div>
<script type="text/javascript">
var toggle = false;
var html;
$(function(){
$("#actionbutton").click(
function(){
toggle = !toggle;
if(toggle){
html = $("#container").html();
$("#container").html("");
} else $("#container").html(html);
})
});
</script>
这个jfiddle演示了我遇到的问题。
5条答案
按热度按时间gojuced71#
答案很简单:使用
.live
以下是更新后的小提琴:http://jsfiddle.net/mrchief/8S5E4/1/
.live
会将事件处理程序附加到"body"(并按DOM元素筛选),以便即使在删除/添加同一DOM元素后,它也会"存活"。您也可以使用
.delegate
实现相同的效果:使用
.delegate
拨弄:http://jsfiddle.net/mrchief/8S5E4/6/我建议在以下情况下使用
.delegate
而不是.live
:live
时,事件会一直冒泡到body
,然后您的处理程序被调用,因此无法取消其冒泡。(从jQuery 1.4开始,可以通过使用上下文参数来防止这种情况:http://api.jquery.com/live/)这里有一篇很棒的文章,很好地解释了differences between live, delegate and bind,并讨论了每种方法的细微差别,感谢@andyb指出这个链接。
tjrkku2a2#
jQuery事件委托救援
注:
.delegate()
is more efficient大于.live()
ymdaylpp3#
发生这种情况是因为你绑定了一个事件到
#testbutton
,而#testbutton
在文档就绪时位于#container
内部。当你清除#container
的HTML时,你也会丢失#testbutton
绑定的click事件。相反,click事件引用的元素不再存在。如果您希望按钮事件持续存在,请尝试使用
live()
绑定或delegate()
父元素中的事件。使用live()
将处理程序附加到与当前选择器匹配的所有元素的事件,无论是现在还是将来。
使用delegate()
根据一组特定的根元素,将处理程序附加到现在或将来与选择器匹配的所有元素的一个或多个事件。
mitkmikd4#
使用live()函数而不是单击
jsFiddle
whlutmcx5#
live()
已弃用。请使用on()
,如有必要,请在document
级别使用它:通过使用
$(document)
,重新生成#testbutton
时其事件处理程序仍将保持不变。