2

我有一个生成 HTML 元素的对象,这些元素也与对象数组相连,假设我们有一个它的实例。因此,当它创建元素时,它还将以下事件侦听器分配给元素的嵌套部分(uploadDelete 类)。

现在这个事件监听器需要调用创建它的对象实例的 delete 方法,并在创建它时分配 i 的值。因为事件在 Window 下,所以需要将实例与 i 值一起传递给匿名函数。

因此,这为事件分配了一个非常独特的功能,并且因为 delete 方法将破坏包含侦听器的元素,我想先将其删除;从我读过的内容来看,否则可能会导致泄漏(?)。我也在使用严格模式,所以不是 arguments.callee。

file.display.getElementsByClassName('uploadDelete')[0].addEventListener('click',
(function(that,i){
    return function() {
        that.delete(i);
    };
})(this,i), false);

我尝试了很多不同的东西,但是当我开始在函数内部的函数内部有一个匿名函数,然后在侦听器中调用它时,我想我应该在这里问一下。我可能对整体问题有一个解决方案,更改其他代码,但如果可以回答这个问题,它仍然会有所帮助。


在 Norguard 的回答的帮助下,这就是我最终要做的事情。由于唯一性源于一个名为 file 的对象,我只是创建了一个新的 file 属性来存储函数:

file.deleteFunction = (function(that,i){
    return function() {
        that.delete(i);
    };
})(this,i);

file.display.getElementsByClassName('uploadDelete')[0].addEventListener('click',file.deleteFunction, false);

然后调用的删除函数删除事件侦听器。

4

1 回答 1

2

一种相对轻松的方法可能是在负责添加和删除侦听器的范围内创建一个对象,该对象构建一个 ID,串行或非串行或非 ID,并将使用该 ID 存储对象中的任何侦听器,返回请求它的任何对象/模块的 ID(或将匿名函数传回给它们)。

// trivial example
var listeners = {},
    i = 0,


add = function (context, func, closure) {
    var enclosed = (function (closure) {
        return function () { /* ... */; func(); };
    }(closure)),
    index = i;

    context.addEventListener("...", enclosed, false);
    listeners[index] = enclosed;
    i += 1;
    return index;
};

add现在将添加您的侦听器,但还将您传递给 addEventListener 的函数存储到listeners对象中。如果你需要一个对 的引用i,你已经在闭包中得到了它,如果你想要的话。

因此,现在当您删除内容时,您只需查找保存在listeners[i].

另一种选择是,如果您不想在一个地方保存一张满是这些的表,无论出于何种原因,都可以捕获 return 语句,而不是返回i,而是返回函数;

// inside of your module
// I'm not usually crazy about `this`, without doing something particular with it,
// but hopefully it illustrates my point
this.cached_func = add(this.el, this.callback.bind(this), this.secret);

所以现在,当需要删除所有内容时,你想关闭你的监听器......

remove(this.cached_func);

尽管如此,您所读到的泄漏仍然是可能的,但主要的罪魁祸首是 IE6/7(及更早版本)。
随着人们远离不良浏览器,这变得不那么重要了。
事实上,在 IE6 中鼓励内存转储可能只是鼓励人们不要使用 IE6 的好方法。

于 2013-03-20T21:41:13.240 回答