47

我有一个使用 jquery-ui-dialog 的页面。每次对话框打开时,页面内容都会使用 ajax 加载。然后它使用 jquery "on()" 绑定一些事件。当对话框关闭时,它将清空其内容。

问题是,我是否需要在 $.empty() 之前取消绑定“.ajax-content”上的事件?

编辑关注 1.任何可能降低 JS 性能?如果我以这种方式清空()数百个节点。

关注2.删除元素是否也会从内存中删除事件(或jquery的任何执行/评估链)?

我暂时没有对他们做任何事情。如果对话框在没有刷新页面的情况下多次打开/关闭,会导致任何问题吗?

代码如下所示:

<div id="jquery-dialog" class="container">
  <div class="ajax-content">
    some buttons....
  </div>
</div>

------after each ajax load------------
$(".ajax-content").on("click", ".button", function(event) {
  //handles the click
});

------on dialog close------------
$("#jquery-dialog").empty();
4

3 回答 3

55

嘿,我知道这是一个老问题,但我认为接受的答案具有误导性。

虽然说您需要取消绑定原始 JS 上的事件以避免旧浏览器(ehem IE)上的内存泄漏是正确的,但调用 remove() 或 empty() 已经为您做到了。

所以你当前对 empty() 的调用应该足够了,它不需要在 unbind() 之前

来自 jQuery 文档 ( http://api.jquery.com/empty/ )

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

于 2013-07-17T20:07:54.317 回答
1

最好解绑,但必须。

大多数浏览器都会正确处理此问题并自行删除这些处理程序。

您还可以看到do-i-need-to-remove-event-listeners

更好的方法来处理这个问题,你可以使用 Event Delegate。

于 2012-10-31T07:39:33.593 回答
-1

Oscar 的回答是不完整的,如果在您的局部(通过 ajax 加载的视图)中您使用 .on() 附加了事件,那么您必须在 .empty() 之前调用 .off()。

查看下面的代码,如果不调用 .off(),则在调用 .empty() 时删除通过标准 .click() 处理程序在 p1.html 中分配的事件,但通过 .on() 在 p2.html 中分配的事件是每次加载部分时都不会删除并重新分配。

索引.html

<html>
<body>
<script src="ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
    <div id='spi' style="padding: 20px; border: 1px solid #666;">
    </div>
    <br/>
    <a href="p1.html" class="spi">Load Partial 1</a> | 
    <a href="p2.html" class="spi">Load Partial 2</a>
    <script type="text/javascript">
    $(document).on('click', 'a.spi' , function(e) {
        e.preventDefault();

        /* 
        !!! IMPORTANT !!!
        If you do not call .off(), 
        events assigned on p2.html via .on()
        are kept and fired one time for each time p2.html was loaded
        */

        $("#spi").off();  


        $("#spi").empty();
        $("#spi").load($(this).attr('href'));
    });
    </script>
</body>
</html>

p1.html

This is the partial 1<br/>
<br/>
<br/>
<a href="javascript:void(0)" id='p1_l1'>Link 1</a>
<br/><br/>
<a href="javascript:void(0)" id='p1_l2'>Link 2</a>
<br/><br/>
<a href="javascript:void(0)" id='p1_l3'>Link 3</a>


<script type="text/javascript">
    $("#p1_l1").click(function(e) {
        e.preventDefault();
        console.debug("P1: p1_l1");
    });
    $("#p1_l2").click(function(e) {
        e.preventDefault();
        console.debug("P1: p1_l2");
    });
</script>

p2.html

This is the partial 2<br/>
<br/>
<br/>
<a href="javascript:void(0)" id='p2_l1'>Link 1</a>
<br/><br/>
<a href="javascript:void(0)" id='p2_l2'>Link 2</a>


<script type="text/javascript">
    $("#spi").on('click', 'a', function(e) {
        e.preventDefault();
        console.debug( 'P2: ' + $(this).attr('id') );
    });
</script>
于 2014-04-10T12:34:15.653 回答