jquery html重置后缺少javascript事件

vlurs2pr  于 2023-03-07  发布在  jQuery
关注(0)|答案(5)|浏览(170)

我遇到过这样的情况: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演示了我遇到的问题。

gojuced7

gojuced71#

答案很简单:使用.live

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

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

    • 解释:**更改DOM时,附加到元素的事件处理程序也会被删除。使用.live会将事件处理程序附加到"body"(并按DOM元素筛选),以便即使在删除/添加同一DOM元素后,它也会"存活"。

您也可以使用.delegate实现相同的效果:

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

使用.delegate拨弄:http://jsfiddle.net/mrchief/8S5E4/6/
我建议在以下情况下使用.delegate而不是.live

  • 您可以取消事件冒泡。当您使用live时,事件会一直冒泡到body,然后您的处理程序被调用,因此无法取消其冒泡。(从jQuery 1.4开始,可以通过使用上下文参数来防止这种情况:http://api.jquery.com/live/
  • 由于您是专门附加到一个DOM元素的,所以它不会在每次单击body上的任何其他DOM元素时被调用,因此性能更高,因为它现在需要做的工作更少。

这里有一篇很棒的文章,很好地解释了differences between live, delegate and bind,并讨论了每种方法的细微差别,感谢@andyb指出这个链接。

tjrkku2a

tjrkku2a2#

jQuery事件委托救援

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

注:.delegate()is more efficient大于.live()

ymdaylpp

ymdaylpp3#

发生这种情况是因为你绑定了一个事件到#testbutton,而#testbutton在文档就绪时位于#container内部。当你清除#container的HTML时,你也会丢失#testbutton绑定的click事件。相反,click事件引用的元素不再存在。
如果您希望按钮事件持续存在,请尝试使用live()绑定或delegate()父元素中的事件。

使用live()

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

将处理程序附加到与当前选择器匹配的所有元素的事件,无论是现在还是将来。

使用delegate()

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

根据一组特定的根元素,将处理程序附加到现在或将来与选择器匹配的所有元素的一个或多个事件。

whlutmcx

whlutmcx5#

live()已弃用。请使用on(),如有必要,请在document级别使用它:

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

通过使用$(document),重新生成#testbutton时其事件处理程序仍将保持不变。

相关问题