是否可以断开Dojo中的所有事件处理程序?

时间:2009-05-15 20:36:51

标签: javascript memory-leaks dojo

我正在使用的一些代码用来自AJAX调用的新HTML替换了一些具有Dojo事件侦听器的HTML元素(使用.innerHTML =)。我已经读过,在替换事件监听器之前,应该使用dojo.disconnect(handle)方法断开事件监听器,以防止内存泄漏。

是否可以派生连接到特定元素的所有句柄,以便我可以将每个句柄传递给.disconnect(句柄),还是由我来维护我的代码中的列表?

2 个答案:

答案 0 :(得分:5)

实际上如果你正在使用小部件,他们通常应该断开tehir destroy()方法中的东西。如果您自己处理节点,我会看到两种方法。

1)手动管理所有连接,意味着将它们存储在某处。 2)可能是更安全的:将所有连接处理程序存储在它们连接的节点中,如下所示:

node._connectHandlers = [];
node._connectHandlers.push(dojo.connect(node, "onclick", ...));

稍后你可以使用

简单地断开它们
dojo.query("*", nodeContainingConnects).forEach(function(node){
    if (typeof node._connectHandlers!="undefined"){
        dojo.forEach(node._connectHandlers, "dojo.disconnect(item)");
    }
});

实际上,这可能效果很好,但可能有更有效的方法来获取节点的所有连接。我只是没找到它。 HTH

答案 1 :(得分:1)

根据Wolfram Kriesing的回答,这可以“改进”:

dojo._connect_tmp = dojo.connect;
dojo.connect = function (obj, event, context, method, dontFix) {
    if(obj._connectHandlers == undefined){ obj._connectHandlers = [];}
    var handler = dojo._connect_tmp (obj, event, context, method, dontFix);
    obj._connectHandlers.push(handler);
    return handler;
};

dojo.iwanttobefree = function (obj) {
   if(obj._connectHandlers == undefined) {
   } else {
      dojo.forEach(obj._connectHandlers, "dojo.disconnect(item)");  
   }
};

然后你可以这样做:

dojo.connect(myObj, 'onfocus', function(){alert('weee')});
dojo.iwanttobefree(myObj);

由于多种原因,替换dojo代码可能非常非常难看,所以也许你想创建自己的命名空间。