Удалить все дочерние элементы узла DOM в JavaScript



как я могу удалить все дочерние элементы узла DOM в JavaScript?



скажем, у меня есть следующий (уродливый) HTML:



<p id="foo">
<span>hello</span>
<div>world</div>
</p>


и я хватаю узел, который я хочу так:



var myNode = document.getElementById("foo");


как я мог удалить детей foo Так что просто <p id="foo"></p> осталось?



могу ли я просто сделать:



myNode.childNodes = new Array();


или я должен использовать некоторые комбинации removeElement?



Я хотел бы, чтобы ответ был прямо вверх дом; хотя дополнительные очки, если вы также предоставляете ответ в jQuery вместе с ответом DOM-only.

944   25  

25 ответов:

Вариант 1 (гораздо медленнее, см. комментарии ниже):

var myNode = document.getElementById("foo");
myNode.innerHTML = '';

Вариант 2 (гораздо быстрее):

var myNode = document.getElementById("foo");
while (myNode.firstChild) {
    myNode.removeChild(myNode.firstChild);
}

в настоящее время принятый ответ неверен в том, что innerHTML медленнее (по крайней мере, в IE и Chrome), Как правильно упомянуто в m93a.

Chrome и FF значительно быстрее используют этот метод (который уничтожит прикрепленные данные jquery):

var cNode = node.cloneNode(false);
node.parentNode.replaceChild(cNode ,node);

в далекую секунду для FF и Chrome, и самый быстрый в IE:

node.innerHTML = '';

InnerHTML не уничтожит ваши обработчики событий или сломает ссылки jquery, он также рекомендуется в качестве решения здесь: https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML

самый быстрый метод манипуляции DOM (все еще медленнее, чем предыдущие два) - это удаление диапазона, но диапазоны не поддерживаются до IE9.

var range = document.createRange();
range.selectNodeContents(node);
range.deleteContents();

другие упомянутые методы кажутся сопоставимыми, но намного медленнее, чем innerHTML, за исключением выброса, jquery (1.1.1 и 3.1.1), который значительно медленнее, чем все остальное:

$(node).empty();

доказательства здесь:

http://jsperf.com/innerhtml-vs-removechild/167 http://jsperf.com/innerhtml-vs-removechild/300 https://jsperf.com/remove-all-child-elements-of-a-dom-node-in-javascript (Новый url для перезагрузки jsperf, потому что редактирование старого url не работает)

Jsperf "за цикл тестирования " часто понимается как" за итерацию", и только первая итерация имеет узлы для удаления, поэтому результаты бессмысленны, во время постинга были неправильно настроены тесты в этой теме.

var myNode = document.getElementById("foo");
var fc = myNode.firstChild;

while( fc ) {
    myNode.removeChild( fc );
    fc = myNode.firstChild;
}

если есть какой-либо шанс, что у вас есть jQuery пострадавших потомков, то вы должны используйте некоторый метод, который будет очищать данные jQuery.

$('#foo').empty();

jQuery .empty() метод гарантирует, что все данные, связанные с удаляемыми элементами jQuery, будут очищены.

если вы просто использовать DOM методы удаления детей, что данные останутся.

Если вы используете jQuery:

$('#foo').empty();

Если вы этого не сделаете:

var foo = document.getElementById('foo');
while (foo.firstChild) foo.removeChild(foo.firstChild);

самый быстрый...

var removeChilds = function (node) {
    var last;
    while (last = node.lastChild) node.removeChild(last);
};

спасибо Андрею Лушникову за его ссылка на jsperf.com (классный сайт!).

используйте современный Javascript, с remove!

const parent = document.getElementById("foo");
while (parent.firstChild) {
    parent.firstChild.remove();
}

это более новый способ записи удаления узла в ES5. Это ваниль JS и читает много лучше, чем предыдущие версии.

большинство пользователей должны иметь современные браузеры или вы можете транспилировать вниз, если это необходимо.

Поддержка Браузеров - 91% Apr 2018

Если вы только хотите иметь узел без его дочерних элементов, вы также можете сделать его копию следующим образом:

var dupNode = document.getElementById("foo").cloneNode(false);

зависит от того, что вы пытаетесь достичь.

element.textContent = '';

это как внутренний текст, кроме стандартного. Это немного медленнее чем removeChild(), но это проще в использовании и не будет иметь большого значения для производительности, если у вас не слишком много вещей для удаления.

вот еще один подход:

function removeAllChildren(theParent){

    // Create the Range object
    var rangeObj = new Range();

    // Select all of theParent's children
    rangeObj.selectNodeContents(theParent);

    // Delete everything that is selected
    rangeObj.deleteContents();
}

есть несколько вариантов для достижения этого:

самый быстрый ():

while (node.lastChild) {
  node.removeChild(node.lastChild);
}

альтернативы (медленнее):

while (node.firstChild) {
  node.removeChild(node.firstChild);
}

while (node.hasChildNodes()) {
  node.removeChild(node.lastChild);
}

бенчмарк с предлагаемыми опциями

Я видел, как люди делают:

while (el.firstNode) {
    el.removeChild(el.firstNode);
}

потом кто-то сказал, используя el.lastNode быстрее

Я думаю, что это самый быстрый:
var children = el.childNodes;
for (var i=children.length - 1; i>-1; i--) {
    el.removeNode(children[i]);
}

что вы думаете?

ps: эта тема стала для меня спасением жизни. мой Firefox аддон был отклонен, потому что я использовал innerHTML. Это уже давно вошло в привычку. тогда я понял это. и я действительно заметил разницу в скорости. при загрузке innerhtml потребовалось некоторое время для обновления, однако с помощью addElement его немедленно!

var empty_element = function (element) {

    var node = element;

    while (element.hasChildNodes()) {              // selected elem has children

        if (node.hasChildNodes()) {                // current node has children
            node = node.lastChild;                 // set current node to child
        }
        else {                                     // last child found
            console.log(node.nodeName);
            node = node.parentNode;                // set node to parent
            node.removeChild(node.lastChild);      // remove last node
        }
    }
}

это приведет к удалению всех узлов в элементе.

в ответ на DanMan, Маартен и Мэтт. Клонирование узла, чтобы установить текст, действительно является жизнеспособным способом в моих результатах.

// @param {node} node
// @return {node} empty node
function removeAllChildrenFromNode (node) {
  var shell;
  // do not copy the contents
  shell = node.cloneNode(false);

  if (node.parentNode) {
    node.parentNode.replaceChild(shell, node);
  }

  return shell;
}

// use as such
var myNode = document.getElementById('foo');
myNode = removeAllChildrenFromNode( myNode );

также это работает для узлов не в dom, которые возвращают null при попытке доступа к parentNode. Кроме того, если вам нужно быть в безопасности, узел пуст перед добавлением контента, это действительно полезно. Рассмотрим пример использования ниже.

// @param {node} node
// @param {string|html} content
// @return {node} node with content only
function refreshContent (node, content) {
  var shell;
  // do not copy the contents
  shell = node.cloneNode(false);

  // use innerHTML or you preffered method
  // depending on what you need
  shell.innerHTML( content );

  if (node.parentNode) {
    node.parentNode.replaceChild(shell, node);
  }

  return shell;
}

// use as such
var myNode = document.getElementById('foo');
myNode = refreshContent( myNode );

Я нахожу этот метод очень полезен при замене строки внутри элемента, если вы не уверены то, что узел будет содержать, вместо того, чтобы беспокоиться о том, как очистить беспорядок, начните с чистого листа.

innerText является победителем! http://jsperf.com/innerhtml-vs-removechild/133. во всех предыдущих тестах внутренний dom родительского узла был удален на первой итерации, а затем innerHTML или removeChild, где применяется к пустому div.

самый простой способ удаления дочерних узлов узла с помощью Javascript

var myNode = document.getElementById("foo");
while(myNode.hasChildNodes())
{
   myNode.removeChild(myNode.lastChild);
}

Как правило, JavaScript использует массивы для ссылки на списки узлов DOM. Таким образом, это будет работать хорошо, если у вас есть интерес к этому через массив HTMLElements. Кроме того, стоит отметить, потому что я использую ссылку на массив вместо JavaScript proto, это должно работать в любом браузере, включая IE.

while(nodeArray.length !== 0) {
  nodeArray[0].parentNode.removeChild(nodeArray[0]);
}

почему мы не следуем простейшему методу здесь "удалить" петлю внутри в то время как.

const foo = document.querySelector(".foo");
while (foo.firstChild) {
  foo.firstChild.remove();     
}
  • выбор родительского div
  • используя метод "remove"внутри цикла While для устранения первого дочернего элемента, пока не останется ни одного.

самый простой способ:

let container = document.getElementById("containerId");
container.innerHTML = "";

простое и быстрое использование для цикла!!

var myNode = document.getElementById("foo");

    for(var i = myNode.childNodes.length - 1; i >= 0; --i) {
      myNode.removeChild(myNode.childNodes[i]);
    }

это не будет работать в <span> тег!

вот что я обычно делаю :

HTMLElement.prototype.empty = function() {
    while (this.firstChild) {
        this.removeChild(this.firstChild);
    }
}

и вуаля, позже вы можете очистить любой элемент DOM с :

anyDom.empty()

другие способы в jQuery

var foo = $("#foo");
foo.children().remove();
or
$("*", foo ).remove();
or
foo.html("");

просто только IE:

parentElement.removeNode(true);

true - означает сделать глубокое удаление - что означает, что все дочерние также удаляются

это чистый javascript я использую не jQuery но работает во всех браузерах даже IE

<div id="my_div">
 <p>i am the first child</p>
 <p>i am another paragraphs</p>
 <p>enven me also i am another paragraphs</p>
</div>
<button id ="my_button>Remove nodes ?</button>

document.getElementById("my_button").addEventListener("click",function(){

  let parent_node =document.getElemetById("my_div");
  let last_child  =parent_node.lastChild;
  while(last_child){
    parent_node.removeChild(last_child);
  }
})

или вы можете просто сделать это

document.getElementById("my_button").addEventListener("click",function(){

 let parent_node =document.getElemetById("my_div");
 parent_node.innerHTML ="";

})

если вы хотите положить что-то обратно в это div на innerHTML наверное лучше.

мой пример:

<ul><div id="result"></div></ul>

<script>
  function displayHTML(result){
    var movieLink = document.createElement("li");
    var t = document.createTextNode(result.Title);
    movieLink.appendChild(t);
    outputDiv.appendChild(movieLink);
  }
</script>

если я использую .firstChild или .lastChild метод displayHTML() функция не работает после этого, но никаких проблем с .innerHTML метод.

С помощью jQuery :

$("#foo").find("*").remove();

Comments

    Ничего не найдено.