动态删除javascript中的元素

时间:2011-10-17 23:33:21

标签: javascript html5 javascript-events

我使用普通的旧javascript(没有jQuery或其他)。

我有一个HTML5应用程序,我想从section元素中删除canvas:

<section id="thumbnails">
    <h1>My Bookmarks:</h1>
    <canvas height="60px" width="100px" data-time="2.1167500019073486"></canvas>
    <canvas height="60px" width="100px" data-time="3.60492205619812"></canvas>
    <canvas height="60px" width="100px" data-time="4.558893203735352"></canvas>
    <canvas height="60px" width="100px" data-time="5.411310195922852"></canvas>
</section>

我使用的代码如下:

document.getElementById('videos').addEventListener('change',function(e){
    var canvasElements=document.getElementById('thumbnails').getElementsByTagName('canvas');
    for(var i=0;i<canvasElements.length;i++){
        document.getElementById('thumbnails').removeChild(canvasElements[i]);
        console.log('removed canvas');
    }
},true);

然而,当代码运行时,并不是所有画布都从该部分删除,我甚至都没有在控制台中看到日志语句。

转到此页面,获取一些缩略图,然后切换到另一个视频:http://laurent-tonon.com/VideoFinal/

我真的不明白......

感谢您的时间

4 个答案:

答案 0 :(得分:7)

问题是getElementsByTagName会返回一个动态nodeList,当您删除项目时,它会在您的下方发生变化。您可以通过以相反的顺序处理数组来解决这个问题,因此删除项目时更改的nodeList的唯一部分是您已经处理的部分,而不是您仍需要执行的部分:

document.getElementById('videos').addEventListener('change',function(e){
    var canvasElements=document.getElementById('thumbnails').getElementsByTagName('canvas');
    for (var i = canvasElements.length - 1; i >= 0; i--) {
        canvasElements[i].parentNode.removeChild(canvasElements[i]);
        console.log('removed canvas');
    }
},true);

像往常一样以正向顺序处理它会导致您删除所有其他项目并留下一半的项目。您删除第一个项目。它将从nodeList中移除,将nodeList中的每个项目向下移动一个插槽。然后,将索引前进到[1]并删除最初的第三项(但现在位于数组的第二个插槽中)。最初是第二个项目的项目现在位于数组的第一个插槽中,您永远不会最终删除它。

反转你处理nodeList的顺序可以解决这个问题,因为从数组中删除的那些是最后的,并且不会改变你仍然需要处理的那些的位置。


我知道这不是一个jQuery问题,并且完全可以用上面的普通javascript解决,但是有时候我会提醒jQuery中有些东西是多么容易:

$("#thumbnails canvas").remove();

答案 1 :(得分:3)

由于您已经依赖于支持html5的浏览器,为什么不使用一些更新的方法:

[].slice.call( document.querySelectorAll( "#thumbnails canvas" ) ).forEach(
    function(v){
    v.parentNode.removeChild(v);
    }
);

答案 2 :(得分:2)

我认为问题是getElementsByTagName()返回实时nodeList,当您删除元素并通过索引引用它们时会导致问题。

试试这个......

while(canvasElements.length) {
    canvasElements[0].parentNode.removeChild(canvasElements[0]);
    console.log('removed canvas');
}

jsFiddle

答案 3 :(得分:1)

为什么这么复杂?

怎么样?
document.getElementById('videos').addEventListener('change',function(e){
    var canvasElements=document.getElementById('thumbnails');
    while (canvasElements.hasChildNodes())
    {
        canvasElements.removeChild(canvasElements.lastChild);
    }
});

或者,更简单的

document.getElementById('videos').addEventListener('change',function(e){
    document.getElementById('thumbnails').innerHTML = '';
});