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

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

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

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

И я хватаю node Я хочу так:

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

Как удалить дочерние элементы foo, чтобы оставить только <p id="foo"></p>?

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

myNode.childNodes = new Array();

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

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

+702
17 окт. '10 в 20:51
источник поделиться
29 ответов

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

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

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

var myNode = document.getElementById("foo");
while (myNode.firstChild) {
    myNode.removeChild(myNode.firstChild);
}
+1387
17 окт. '10 в 20:52
источник

В настоящее время принят неверный ответ о том, что 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 (все еще медленнее, чем предыдущие два) - это удаление Range, но диапазоны не поддерживаются до 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 "per-test-loop" часто понимается как "per-iteration", и только у первой итерации есть узлы для удаления, поэтому результаты не имеют смысла, на момент публикации в этом потоке были неправильно настроены тесты.

+89
09 апр. '14 в 15:04
источник
var myNode = document.getElementById("foo");
var fc = myNode.firstChild;

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

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

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

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

Если вы просто используете методы t12 > удаления детей, эти данные будут оставаться.

+41
17 окт. '10 в 20:57
источник

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

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

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

var foo = document.getElementById('foo');
while (foo.firstChild) foo.removeChild(foo.firstChild);
+34
17 окт. '10 в 21:02
источник

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

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

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

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

Поддержка браузеров - 94% май 2019

+33
15 нояб. '16 в 9:57
источник

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

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

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

РЕДАКТИРОВАТЬ: чтобы быть ясным, нет никакой разницы в производительности в Chrome между firstChild и lastChild. Верхний ответ показывает хорошее решение для производительности.

+19
02 апр. '13 в 18:02
источник

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

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

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

+9
17 окт. '10 в 21:13
источник
element.textContent = '';

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

+6
28 мар. '14 в 17:13
источник

Здесь другой подход:

function removeAllChildren(theParent){

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

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

    // Delete everything that is selected
    rangeObj.deleteContents();
}
+5
11 мар. '14 в 20:27
источник

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

// @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. Кроме того, если вам нужно быть в безопасности, node пуст, прежде чем добавлять контент, это действительно полезно. Рассмотрим пример использования ниже.

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

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

+4
15 мар. '13 в 20:40
источник

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

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

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

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

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

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

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

+3
27 янв. '17 в 13:49
источник

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

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

как вы думаете?

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

+3
03 февр. '14 в 10:03
источник
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
        }
    }
}

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

+3
01 февр. '14 в 13:46
источник

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

var myNode = document.getElementById("foo");
while(myNode.hasChildNodes())
{
   myNode.removeChild(myNode.lastChild);
}
+2
18 июл. '16 в 18:12
источник

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

+2
27 янв. '14 в 11:08
источник

Использование диапазона диапазона чувствует себя наиболее естественным для меня:

for (var child of node.childNodes) {
    child.remove();
}

Согласно моим измерениям в Chrome и Firefox, он примерно на 1,3 раза медленнее. В нормальных обстоятельствах это, возможно, не имеет значения.

+2
06 дек. '18 в 20:03
источник

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

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

И voila, позже вы можете удалить любой элемент dom с помощью:

anyDom.empty()
+2
09 сент. '18 в 20:27
источник

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

while(nodeArray.length !== 0) {
  nodeArray[0].parentNode.removeChild(nodeArray[0]);
}
+1
13 июл. '17 в 21:14
источник

Просто увидел, что кто-то упоминает этот вопрос в другом, и думал, что добавлю метод, который я еще не видел:

function clear(el) {
    el.parentNode.replaceChild(el.cloneNode(false), el);
}

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

Функция clear выполняет элемент и использует родительский узел, чтобы заменить его копией без нее. Не так много прироста производительности, если элемент разрежен, но когда элемент имеет кучу узлов, реализуется производительность.

0
14 нояб. '18 в 21:26
источник

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

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

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

$("#target").empty(); 

пример кода:

$("#button").click(function(){
    $("#target").empty();
});
0
20 мар. '17 в 4:24
источник

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

var foo = $("#foo");
foo.children().remove();
or
$("*", foo ).remove();
or
foo.html("");
-1
16 окт. '11 в 18:09
источник

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

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

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

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

-1
18 авг. '18 в 18:30
источник

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

let container = document.getElementById("containerId");
container.innerHTML = "";
-1
05 февр. '18 в 14:24
источник

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

parentElement.removeNode(true);

true - означает глубокое удаление - это означает, что все дочерние элементы также удалены

-1
15 дек. '16 в 12:31
источник

Вариант 2 из выигрышного ответа.

function emptyElement(element) {
      var myNode = element;
      while (myNode.firstChild) {
          myNode.removeChild(myNode.firstChild);
      }
    }

   emptyElement(document.body)
-2
19 окт. '16 в 17:43
источник

Если вы хотите вернуть что-то в это 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.

-3
18 окт. '17 в 7:02
источник

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

   <div id="my_div">
    <p>Paragraph one</p>
    <p>Paragraph two</p>
    <p>Paragraph three</p>
   </div>
   <button id ="my_button>Remove nodes ?</button>

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

  let parent_node =document.getElemetById("my_div"); //Div which contains paagraphs

  //Let find numbers of child inside the div then remove all
  for(var i =0; i < parent_node.childNodes.length; i++) {
     //To avoid a problem which may happen if there is no childNodes[i] 
     try{
       if(parent_node.childNodes[i]){
         parent_node.removeChild(parent_node.childNodes[i]);
       }
     }catch(e){
     }
  }

})

or you may simpli do this which is a quick way to do

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

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

})
-4
30 мар. '17 в 6:02
источник

с jQuery:

$("#foo").find("*").remove();
-7
17 окт. '10 в 20:54
источник

Посмотрите другие вопросы по меткам или Задайте вопрос