html重置后javascript事件丢失 [英] javascript event missing after html reset

查看:106
本文介绍了html重置后javascript事件丢失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一种情况,在某种程度上,div的html内容被更改为其他内容,然后被更改回来。一些jquery ui控件是行为不端的。我已将问题简化为以下代码段,它基本上显示与该按钮关联的事件处理程序不再触发。我假设当它们消失时,这些都是垃圾收集的。所以我的问题是 -



如何防止事件处理程序在DOM中丢失时被垃圾回收



我知道我可以重新分配 click()函数,但由于我使用的是外部库(jquery ui),我真的不知道它对我的控件做了什么。我只是希望他们的活动恢复原状。

 < div id =container> 
< p>这个容器有一个按钮,它会忘记它的click()...< / p>
< input id =testbuttontype =buttonvalue =Click Me!/>
< / div>

< script type =text / javascript>
$(function(){
$(#testbutton)。click(
function(){
alert(按钮已被点击!);
})
});
< / script>

< div>
< p> ...当此按钮重新设置html< / p>时
< input id =actionbuttontype =buttonvalue =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 演示了我遇到的问题。

解决方案

简单回答:使用 .live

  $(function(){
$(#testbutton ).live('click',
function(){
alert(按钮已被点击!);
})
});

这是更新的小提琴: http://jsfiddle.net/mrchief/8S5E4/1/



说明:当您更改DOM时,附加元素的事件处理程序也会被删除。使用 .live 将事件处理程序附加到body(并按DOM元素过滤),以便即使在删除/添加相同的DOM元素后它也存在。



使用 .delegate 也可以达到同样的效果:

  $(function(){
$('#container')。delegate('#testbutton','click',
function(){
alert(按钮已被点击!);
})
});使用 .delegate http://jsfiddle.net/mrchief/8S5E4/6/



我建议在 .live 上使用 .delegate




  • 您可以取消事件冒泡。当你使用 live 时,事件会一直冒泡到 body ,然后你的处理程序被调用,所以有没办法取消它的冒泡。 (从jQuery 1.4开始,可以通过使用上下文参数来防止这种情况: http://api.jquery.com/ live /

  • 因为你特意附加到DOM元素,所以每次点击身体上的任何其他DOM元素时都不会调用它,因此,因为它现在必须做更少的工作才能提高性能。



这是一篇精彩的文章,精美地解释了实时,委托和绑定之间的差异并讨论了细微差别每种方法。感谢@andyb指出这个链接。


I have a situation where at one point the html contents of a div are changed to something else, and then are changed back. Some of jquery ui controls are misbehaving. I've reduced the problem to the following snippet, which basically shows that the event handler associated with the button doesn't fire anymore. I am assuming that these were garbage collected at some point when they were gone. So my question is -

How do I prevent event handlers from being garbage collected when they are missing from the DOM?

I understand that I could just reassign the click() function, but since I'm using an external library (jquery ui), i don't really know what's it doing with my controls. I'd just want their events restored as they were before.

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

This jfiddle demonstrates the problem that I'm having.

解决方案

Simple answer: use .live

$(function(){ 
    $("#testbutton").live('click',
        function(){
            alert("Button has been clicked!");
    })
});

Here's the updated fiddle: http://jsfiddle.net/mrchief/8S5E4/1/

Explanation: When you alter the DOM, event handlers attached the element are also removed. Using .live attaches the event handlers to 'body' (and filters by DOM element) so that it 'lives' even after removing/adding the same DOM element.

You can achieve the same effect using .delegate also:

$(function(){ 
    $('#container').delegate('#testbutton', 'click',
        function(){
            alert("Button has been clicked!");
    })
});

fiddle using .delegate: http://jsfiddle.net/mrchief/8S5E4/6/

I would recommend using .delegate over .live for:

  • You can cancel event bubbling. When you use live, the event bubbles up all the way to body and then your handler gets called, so there is no way to cancel its bubbling. (As of jQuery 1.4, this can be prevented by using a context argument: http://api.jquery.com/live/)
  • Since you're attaching to a DOM element specifically, it doesn't get invoked everytime there is a click on any other DOM element on body and hence, is more performant as it has to do less work now.

Here's a great article that beautifully explains the differences between live, delegate and bind and discusses about the nuances of each approach. Thanks to @andyb for pointing this link out.

这篇关于html重置后javascript事件丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆