development

JavaScript에서 DOM 노드의 모든 자식 요소 제거

big-blog 2020. 9. 29. 08:07
반응형

JavaScript에서 DOM 노드의 모든 자식 요소 제거


JavaScript에서 DOM 노드의 모든 자식 요소를 제거하려면 어떻게해야합니까?

다음과 같은 (추악한) 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합니까?

DOM이 똑바로되는 대답을 원합니다. DOM 전용 답변과 함께 jQuery에서 답변을 제공하는 경우 추가 포인트가 있습니다.


옵션 1 (훨씬 느림, 아래 설명 참조) :

doFoo.onclick = () => {
  const myNode = document.getElementById("foo");
  myNode.innerHTML = '';
}
<div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
  <span>Hello</span>
</div>
<button id='doFoo'>Remove Via innerHTML</button>

옵션 2 (훨씬 빠름) :

doFoo.onclick = () => {
  const myNode = document.getElementById("foo");
  while (myNode.firstChild) {
    myNode.removeChild(myNode.firstChild);
  }
}
<div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
  <span>Hello</span>
</div>
<button id='doFoo'>Remove Via removeChild</button>


innerHTMLm93a가 올바르게 언급했듯이 현재 허용되는 대답은 (적어도 IE와 Chrome에서) 느리다 는 것에 대한 잘못된 것입니다.

이 방법을 사용하면 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();

언급 된 다른 방법은 비슷해 보이지만, 다른 어떤 것보다 상당히 느린 특이 치인 jquery (1.1.1 및 3.1.1)를 제외하고는 innerHTML보다 훨씬 느립니다.

$(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"으로 이해되며 첫 번째 반복에만 제거 할 노드가 있으므로 결과가 무의미합니다. 게시 당시이 스레드에 테스트가 잘못 설정되었습니다.


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자식을 제거하는 방법을 사용하면 해당 데이터가 유지됩니다.


최신 자바 스크립트를 remove!

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

이것은 ES5에서 노드 제거를 작성하는 새로운 방법입니다. 바닐라 JS이며 이전 버전보다 훨씬 더 잘 읽습니다 .

대부분의 사용자는 최신 브라우저를 사용하거나 필요한 경우 트랜스 파일 할 수 있습니다.

브라우저 지원 -2019 년 5 월 94 %


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 (멋진 사이트!) 대한 링크에 대해 Andrey Lushnikov에게 감사드립니다 .

편집 : 명확하게 말하자면 firstChild와 lastChild 사이의 Chrome 성능 차이는 없습니다. 최고의 답변은 성능에 대한 좋은 솔루션을 보여줍니다.


자식없이 노드 만 갖고 싶다면 다음과 같이 복사본을 만들 수도 있습니다.

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

달성하려는 목표에 따라 다릅니다.


element.textContent = '';

표준을 제외하고는 innerText와 같습니다. 그건 약간 느린 것보다 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();
}

DanMan, Maarten 및 Matt에 대한 답변입니다. 노드를 복제하여 텍스트를 설정하는 것은 내 결과에서 실제로 실행 가능한 방법입니다.

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

또한 이것은 parentNode에 액세스하려고 할 때 null을 반환하는 dom에없는 노드에 대해 작동합니다. 또한 콘텐츠를 추가하기 전에 노드가 비어 있으면 안전해야하는 경우 매우 유용합니다. 아래의 사용 사례를 고려하십시오.

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

이 방법은 요소 내부의 문자열을 교체 할 때 매우 유용하다는 것을 알았습니다. 노드가 무엇을 포함 할 것인지 확실하지 않으면 엉망을 정리하는 방법을 걱정하는 대신 새로 시작하십시오.


이를 달성하기위한 몇 가지 옵션이 있습니다.

가장 빠른 ():

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

어떻게 생각해?

추신 :이 주제는 저에게 생명의 은인이었습니다. 내 firefox 애드온이 innerHTML을 사용했기 때문에 거부되었습니다. 그것은 오랫동안 습관이었습니다. 그런 다음 나는 이것을 foudn. 그리고 나는 실제로 속도 차이를 발견했습니다. 로드시 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
        }
    }
}

그러면 요소 내의 모든 노드가 제거됩니다.


innerText가 승자입니다! http://jsperf.com/innerhtml-vs-removechild/133 . 모든 이전 테스트에서 부모 노드의 내부 dom은 첫 번째 반복에서 삭제 된 다음 빈 div에 적용된 innerHTML 또는 removeChild가 삭제되었습니다.


Simplest way of removing the child nodes of a node via Javascript

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

Here is what I usually do :

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

And voila, later on you can empty any dom element with :

anyDom.empty()

Using a range loop feels the most natural to me:

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

According to my measurements in Chrome and Firefox, it is about 1.3x slower. In normal circumstances, this will perhaps not matter.


Generally, JavaScript uses arrays to reference lists of DOM nodes. So, this will work nicely if you have an interest in doing it through the HTMLElements array. Also, worth noting, because I am using an array reference instead of JavaScript proto's this should work in any browser, including IE.

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

Why aren't we following the simplest method here "remove" looped inside while.

const foo = document.querySelector(".foo");
while (foo.firstChild) {
  foo.firstChild.remove();     
}
  • Selecting the parent div
  • Using "remove" Method inside a While loop for eliminating First child element , until there is none left.

Just saw someone mention this question in another and thought I would add a method I didn't see yet:

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

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

The clear function is taking the element and using the parent node to replace itself with a copy without it's children. Not much performance gain if the element is sparse but when the element has a bunch of nodes the performance gains are realized.


Other ways in jQuery

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

simply only IE:

parentElement.removeNode(true);

true - means to do deep removal - which means that all child are also removed


The easiest way:

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

simple and fast using for loop!!

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

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

this will not work in <span> tag!


If you want to put something back into that div, the innerHTML is probably better.

My example:

<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>

If I use the .firstChild or .lastChild method the displayHTML() function doesnt work afterwards, but no problem with the .innerHTML method.


This is a pure javascript i am not using jQuery but works in all browser even IE and it is verry simple to understand

   <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 ="";

})

with jQuery :

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

참고URL : https://stackoverflow.com/questions/3955229/remove-all-child-elements-of-a-dom-node-in-javascript

반응형