Проблема в том, что 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();