【问题标题】:Memory leak with unused event handler in javascriptjavascript中未使用的事件处理程序的内存泄漏
【发布时间】:2012-08-23 16:34:34
【问题描述】:

我的情况是,我进行了很多 ajax 调用来更改 html 的同一部分。这个 html 代表一个网格。在 ajax 调用中更改 html 后,我将事件处理程序附加到网格的事件。当用户单击刷新按钮时,我执行相同的 ajax 调用来设置新的 html 代码,并再次添加一个事件处理程序来监听网格的事件。

如果之前的事件处理程序仍在内存中,我想知道每次刷新网格并添加新的事件处理程序,如果是,在这种情况下最佳做法是什么? (例如,如果在放置新 html 之前存在,则取消绑定事件处理程序)

这是我所做的一个例子:

$.get(this.config.actionLoggingUserListUrl, viewModel, function (data) {
    MyNamespace.ui.hideGridAnimation($("#LoggingActionUsersList"));

    if (data.success) {
        $("#validationSummary").html("");

        $("#usersList").html(data.result);

        $("#LoggingActionUsersList").click(function() {
            console.log("Here is my event handler attached multiple times!");
        });
    }
    else {
        $("#validationSummary").html(data.result);

        $("#usersList").html("");
    }
});

请注意,我在这种情况下所说的事件处理程序是:

$("#LoggingActionUsersList").click(function() {
   console.log("Here is my event handler attached multiple times!");
});

【问题讨论】:

  • 您肯定会在每次代码运行时将新的事件处理程序添加到已经存在的事件处理程序中。您可以使用“unbind”取消绑定,或者只是跟踪处理程序是否已经绑定。
  • jQuery .html() 从被.html() 替换的元素中隐式清除所有 (jQuery) 处理程序和 (jQuery) 数据。因此,如果您要附加处理程序的这个元素被上面的 .html() 调用替换,那么您不需要显式分离它。

标签: javascript jquery ajax javascript-events event-handling


【解决方案1】:

事件处理程序堆栈,所以是的,这是一个内存泄漏。可能是一个相当微不足道的问题,但它更多的是原理而不是效果。除非出于某种原因您确实需要动态事件处理程序(很少使用的东西,因为它没有很多实际用途),我强烈建议将事件处理程序分配从 ajax 调用中提取出来。

如果您确实需要更改事件处理程序,那么聪明的方法是让您的事件处理程序足够聪明,以便对分配给它的对象有一点了解。这样,您就可以让事件处理程序中的逻辑根据对象的当前身份执行不同的操作,而不是每次都添加新事件。

【讨论】:

  • 这也可以用于清除堆栈,并且是一个简单的更改:$("#LoggingActionUsersList").unbind().click(...)
  • “因为它没有很多实际用途” 每当您附加一个带参数的事件处理程序时,您都必须将参数包装在一个函数中,不是吗?除了从this 值中获取所有动态信息之外,还有其他解决方案吗?
【解决方案2】:

为什么每次打电话都要绑定?

您每次都添加到堆栈中。你没有替换它。最好的解决方案是使用一次并执行一次。

其他解决方案是在添加点击事件之前取消绑定点击事件。这个解决方案的问题是,如果有其他东西添加了点击事件,你只是将它删除了。

【讨论】:

    猜你喜欢
    • 2012-10-29
    • 2011-01-13
    • 1970-01-01
    • 2012-05-31
    • 1970-01-01
    • 2012-07-01
    • 2010-09-06
    • 2012-04-20
    • 1970-01-01
    相关资源
    最近更新 更多