在JavaScript中,一个对象如何在事件发生时自我销毁?

6

我有一个函数,可以动态创建一个DIV。但是现在,我想在onclick事件中销毁这个对象,但我不知道如何实现。

function creatediv(id) {

    var newdiv = document.createElement('div');
    newdiv.setAttribute('id', id);
    newdiv.onclick=function(){this=null;};  //bad function
    document.body.appendChild(newdiv);

} 

我错过了什么吗?

谢谢。

3个回答

11

仅将其设置为null并不会销毁它。您需要从文档树中删除它,同时确保没有指向它的引用。

function creatediv(id) {
    var newdiv = document.createElement('div');
    newdiv.setAttribute('id', id);
    newdiv.onclick=function(e) {
        this.parentNode.removeChild(this);
    };  
    document.body.appendChild(newdiv);
    newdiv = null;//required in IE to prevent memory leak
}

什么?事件目标可能是newdiv内部的一个节点。在提问者的实际代码中,newdiv肯定被其他节点填充。如果是这种情况,你的代码将从DOM树中删除错误的元素。 - Crescent Fresh

5

我认为被接受的答案是错误的。首先,它没有考虑包含子节点的newdiv,因此建议的删除例程通过闭包(IE)维护了一个内存泄漏的危险。其次,由于'newdiv = null'的位置,creatediv函数立即销毁刚刚创建的元素。 我建议在单击处理程序中使用Douglas Crockford的purge函数,将d替换为this。

function purge(d) {
    var a = d.attributes, i, l, n;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            n = a[i].name;
            if (typeof d[n] === 'function') {
                d[n] = null;
            }
        }
    }
    a = d.childNodes;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            purge(d.childNodes[i]);
        }
    }
}

你说得对。我将根据你的建议纠正我的脚本。 - RSilva
你说的childNodes是对的,但我不认为将newDiv设置为null会将其销毁。这只是在将变量添加到DOM树后取消了对该变量的引用。 - Chetan S
@Chetan:没错,div已经被添加到DOM树中了,是我的错误。无论如何,在函数完成时,div都会被取消引用吧? - KooiInc
@Renzo Kooi:不适用于IE7及更早版本。即使在函数完成后,变量newDiv仍然可以在事件处理程序闭包内访问。由于闭包现在是newDiv元素的属性,所以存在循环引用。这就是Crockford建议在删除元素之前先删除事件处理程序的原因。 - Chetan S

0
function removeElement(divNum) {
  var d = document.getElementById('myDiv');
  var olddiv = document.getElementById(divNum);
  d.removeChild(olddiv);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接