Сегодня я обнаружил в Javascript что-то вроде «странного поведения» для меня. Давайте предположим, что следующий минимальный пример:Элегантный способ динамического обновления HTMLCollections
HTML:
<div id="test">
<span>1</span>
<span>2</span>
</div>
JS:
var div = document.getElementById('test');
var spans = div.getElementsByTagName('span');
div.removeChild(spans[0]);
div.removeChild(spans[1]);
(скрипка: http://jsfiddle.net/SkYJg/)
Теперь, при запуске сценария, я получаю сообщение об ошибке:
TypeError: Argument 1 of Node.removeChild is not an object.
Сблизившись, выяснилось, что spans[1]
имеет значение после того, как первый был удален. И действительно, следующий код
var div = document.getElementById('test');
var spans = div.getElementsByTagName('span');
console.log(spans.length);
div.removeChild(spans[0]);
console.log(spans.length);
div.removeChild(spans[1]);
дает 2
при первой операции журнала, но 1
во второй раз.
Теперь ясно, что здесь происходит: после первого? был удален из DOM, это не часть для того, чтобы HTMLCollection
хранился внутри spans
.
У меня всегда было впечатление, что объект HTMLCollection
-Object содержит ссылки на все объекты, которые он содержит. Я не изменял коллекцию нигде после ее создания. Поэтому я подумал (но это было неправильно, очевидно), что коллекция будет вести себя как массив: ссылки остаются там до тех пор, пока я не удалю их вручную.
Я просмотрел specification at MDN. И действительно, richt наверху говорит: HTMLCollections in the HTML DOM are live; they are automatically updated when the underlying document is changed.
Единственный способ, которым я мог подумать, чтобы предотвратить это, - это перебрать коллекцию, прежде чем что-либо делать с ней, скопировать все ссылки на массив и использовать массив для получить доступ к ним впоследствии. Но это выглядит так ужасно громоздко для меня ... есть ли лучшее решение? Как какой-то способ сделать статическую коллекцию или скопировать ее без циклирования?
(в минимальном примере я мог бы просто удалить spans[0]
дважды, конечно, но в действительности это не так просто).
[Изменить]: После просмотра ответа Тейму я повторяю: это НЕ так просто в моем реальном коде (это слишком сложно, чтобы показать его здесь полностью). Уверяю вас, мне действительно нужен произвольный доступ ко всем элементам, которые были внутри этой коллекции, удалены или нет.
Если это касается удаления узлов, то самым простым способом является [цикл через NodeList в обратном порядке] (http://stackoverflow.com/questions/18105426/javascript-function-not-getting-all-values- первый раз/18105542 # 18105542). – CBroe
Это не - см. Править. Может быть, это было более ясно. –
Или вы можете удалить '1', затем' 0'. Я не уверен на 100%, чего вы пытаетесь достичь? – Xotic750