Действительно ли removeChild удаляет элемент?

Действительно ли функция removeChild полностью удаляет дочерний узел? Или он просто удаляет элемент, являющийся дочерним элементом указанного парант-узла? Если он на самом деле не удаляет элемент, есть ли способ полностью удалить элемент?


person Yunus Eren Güzel    schedule 04.03.2011    source источник


Ответы (4)


Метод removeChild просто удаляет его из родительского. Если это видимый элемент страницы, он будет удален со страницы.

Но в Javascript есть сборка мусора. Это означает, что сам объект узла будет существовать до тех пор, пока на него ссылается любая переменная. Таким образом, вы можете назначить узел переменной, использовать removeChild, чтобы «отсечь» его от родительского узла, а затем вставить или добавить его к какому-либо другому узлу, тем самым эффективно перемещая его по странице.

Следующий код удалит узел и подождет 10 секунд, прежде чем повторно добавить его в дерево (и, следовательно, на страницу):

var oldNode = someNode.removeChild(...);
setTimeout(function () {
  document.documentElement.appendChild(oldNode);
}, 10000);

Это означает, что объект узла не был удален из памяти, потому что еще есть переменная, указывающая на него (а именно, oldNode).

Другой случай:

var node = document.getElementById('test');
// ... do stuff
node.parentElement.removeChild(node);
// 'node' still exists, but has been removed from the page
// ... do some more stuff
node = document.getElementById('hello');
// The variable 'node' now points to something else; 
//  this means the original node will be deleted from memory

Если, с другой стороны, вы не переназначаете удаленный узел другой переменной, к нему больше нельзя будет получить доступ (не через дерево документа, поскольку он был удален оттуда; а не через переменная JS); поэтому Javascript автоматически очистит его из памяти:

someNode.removeChild(...);

Назначение удаленного узла переменной, а затем присвоение этой переменной null (или чего-либо еще) - как предлагает Марк Б в своем ответе - совершенно не нужно и, ИМХО, глупо.

person Martijn    schedule 04.03.2011

Это полностью удалит узел:

someNode.removeChild(...);

Это удалит узел из DOM, чтобы он не был виден, но сохранит его, чтобы вы могли вставить его в другое место:

oldNode = someNode.removeChild(...);
person awm    schedule 04.03.2011
comment
Первый пример правильный, но у меня была ситуация, когда он не работал, например var aChild = document.createElement(...); someNode.appendChild(aChild); ... someNode.removeChild(aChild); Узел остается из-за ссылки на переменную aChild. В этом случае вам нужно delete aChild, чтобы завершить работу. - person CyberFonic; 09.05.2012
comment
Из другого контекста (где вы можете не знать, есть ли другие ссылки на удаленный узел) вы можете проверить, в каком состоянии находится удаленный узел, с помощью node.parentElement == null - person Eric Nguyen; 30.01.2014
comment
Это не учитывает другие ссылки на узел. Это означает, что если на узел имеется ссылка в другом месте, removeChild не удалит узел полностью. - person Hal Carleton; 06.08.2015
comment
@moss Вы правы, и к тому же вы излишне педантичны. Фактически, даже если на него нет ссылок, узел не удаляется полностью до тех пор, пока не будет произведена сборка мусора. Дело в том, что removeChild() удаляет узел из DOM, и вы можете сохранить его для дальнейшего использования (2-й пример) или нет (1-й пример), как вам нравится. - person awm; 10.08.2015
comment
Не думаю, что педантично упоминать, что узел не будет полностью удален из памяти, если на него есть ссылка в другом месте. Это может быть бесполезно для OP, но тот, кто позже наткнется на этот вопрос, может найти эту информацию полезной. - person Hal Carleton; 17.08.2015

removeChild удаляет элемент из dom, но он также возвращается из функции в случае, если вы выполняете удаление, чтобы повторно вставить его в другое место. Вам придется убить это возвращаемое значение, чтобы действительно избавиться от удаленного узла:

oldNode = someNode.removeChild(...);
oldNode = null;
person Marc B    schedule 04.03.2011
comment
Разве просто не присвоение возвращаемого значения чему-либо имело бы тот же эффект? - person awm; 04.03.2011
comment
Null удобен и делает очевидным, что вы теряете ценность. выполнение oldNode = 'delete this node please'; кажется пустой тратой персонажей. - person Marc B; 04.03.2011
comment
Я думаю, что OP означает удаление элемента из рендеринга, когда говорят удалить элемент, т.е. они не полностью понимают, что удаление элемента из дерева DOM всегда приведет к его исчезновению. Нет абсолютно никаких причин для хранения возвращаемого значения в переменной; в лучшем случае это вводит в заблуждение. - person Jon; 04.03.2011

Если вы действительно хотите удалить элемент dom. Одного removeChild недостаточно. Это согласно Стиву Саундерсу, который является автором YSlow. Вам нужно использовать удаление

person Arun George    schedule 09.11.2011