Nik*_*sov 3 javascript yui dom memory-leaks
我们正在使用YUI的onclick事件,但我们会快速创建和删除圆顶节点,这会导致内存泄漏.
考虑下面的示例代码,我们有很多次3个嵌套的div.顶部和底部div附加了YUI onclick事件.什么是摆脱那些dom元素而不是泄漏内存的正确方法:
我真的没有任何想法.如您所见,我尝试实现自己的destroy功能.实际上destroy工作并且不泄漏,但它很慢.
该destroy2函数是YUI destroy函数的'copy',我们用它来调试问题所在.看起来YUI的递归清理无法在_instances字典中找到子节点
<!DOCTYPE html5>
<html>
<head>
<script src="http://yui.yahooapis.com/3.4.1/build/yui/yui-min.js"></script>
</head>
<body>
<div id="main">hi there</div>
<script>
YUI().use("node", "event", function(Y) {
window.Y = Y;
function destroy(node) {
(new Y.Node(node)).destroy();
var children = node.children;
for (var i = 0; i<children.length; i++) {
destroy(children[i]);
}
}
function destroy2(node, recursive) {
var UID = Y.config.doc.uniqueID ? 'uniqueID' : '_yuid';
// alert(1);
if (recursive) {
var all = node.all("*");
// alert(all);
Y.NodeList.each(all, function(n) {
instance = Y.Node._instances[n[UID]];
// alert(instance);
if (instance) {
destroy2(instance);
}
});
}
node._node = null;
node._stateProxy = null;
delete Y.Node._instances[node._yuid];
// node.destroy();
}
var main = new Y.Node("#main");
var divs = [];
var iter = 0;
Y.later(10, window, function() {
iter ++ ;
var i;
for (i=0; i<divs.length; i++) {
var d = divs[i];
d.parentNode.removeChild(d);
// (new Y.Node(d)).destroy(true);
//destroy(d);
//destroy2(new Y.Node(d), true);
(new Y.Node(d)).destroy(true);
}
divs = [];
for (i=0; i<1000; i++) {
var d = document.createElement("div");
var i1;
var i2;
d.appendChild(i1=document.createElement("div"));
i1.appendChild(document.createTextNode('inner 1'));
i1.appendChild(i2=document.createElement("div"));
i2.appendChild(document.createTextNode('inner 2'));
Y.on("click", function() {
alert("inner click")
}, i2);
// try to tell YUI to make Node elements
Y.Node.one(d);
Y.Node.one(i1);
Y.Node.one(i2);
// new Y.Node(d);
// new Y.Node(i1);
// new Y.Node(i2);
d.appendChild(document.createTextNode("this is div " + iter + " " + i));
Y.on("click", function(){ alert("you clicked me");}, d);
main.appendChild(d);
//divs.push(i2);
divs.push(d);
}
}, null, true);
})
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
我不确定你在这里想要完成什么,但是在包含的代码中有一些突出的东西:
var Y = YUI().use(…)- use()返回YUI实例.无需分配window.Y = Y;Y.one(el)而不是new Y.Node(el)或Y.Node.one(el)Y.Node.create('<div><div>inner 1<div>inner2</div></div></div>').您可能不需要每个div的Node实例其中最重要的是#3和#4.如果你使用Node.create(或append,insert,prepend等),通过在标记不会对每一个元素,只有最外层的元素创建节点.如果使用事件委派,则不需要单独的节点,这意味着您可以添加div结构并立即调用node.destroy()(注意不通过,true因为内部标记没有需要清除的节点). node.destroy()将清除事件监听器,因为您正在使用事件委派,所以您没有这些监听器,并且_instances在任何用户交互之前从字典中删除节点以释放内存.如果用户单击其中一个节点,则委托处理程序将捕获该事件,并为该e.target元素创建节点.您可以this.destroy()在事件处理程序内部调用以重新清除target节点.
YMMV,考虑到你的代码片段并不反映真实的用例.您也可以在freenode上停留#yui以获得帮助或解决问题.
| 归档时间: |
|
| 查看次数: |
1401 次 |
| 最近记录: |