Динамически удалять элементы в JavaScript - PullRequest
0 голосов
/ 18 октября 2011

Я использую старый добрый javascript (без jQuery или другого).

У меня есть приложение HTML5, в котором я хочу удалить холст из элемента раздела:

<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);

Однакокогда код выполняется, не все холсты удаляются из этого раздела, и я даже не вижу оператора log в консоли.

Перейдите на эту страницу, возьмите несколько миниатюр и переключитесь на другое видео: http://laurent -tonon.com / VideoFinal /

Я действительно не понимаю ...

Спасибо за ваше время, ребята

Ответы [ 4 ]

7 голосов
/ 18 октября 2011

Проблема в том, что getElementsByTagName возвращает динамический список узлов, который изменится под вами при удалении элементов.Вы можете обойти это, обработав массив в обратном порядке, поэтому единственная часть 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] и удаляете то, что изначально было третьим элементом (но теперь находится во 2-м слоте в массиве).Элемент, который изначально был вторым элементом, теперь находится в первом слоте в массиве, и вы никогда не будете в конечном итоге удалять его.

В обратном порядке, в котором вы обрабатываете, nodeList решает эту проблему, поскольку те, которые были удалены измассив находится в конце и не меняет положение тех, которые вам еще нужно обработать.


Я знаю, что это не вопрос jQuery, и он прекрасно решается с помощью простого простого javascript,но сейчас такие времена, когда мне напоминают, как легко некоторые вещи в jQuery:

$("#thumbnails canvas").remove();
3 голосов
/ 18 октября 2011

Поскольку вы уже используете браузер с поддержкой html5, почему бы не использовать некоторые обновленные методы:

[].slice.call( document.querySelectorAll( "#thumbnails canvas" ) ).forEach(
    function(v){
    v.parentNode.removeChild(v);
    }
);
2 голосов
/ 18 октября 2011

Я полагаю, что проблема в getElementsByTagName() возвращает текущее значение nodeList, которое вызывает проблемы при удалении элементов и обращении к ним по их индексу.

Попробуйте это...

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

jsFiddle .

1 голос
/ 18 октября 2011

Почему так сложно? Как насчет

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 = '';
});

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...