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 A : 지우기 innerHTML
.
- 이 방법은 간단하지만 브라우저의 HTML 파서를 호출하기 때문에 고성능 응용 프로그램에는 적합하지 않을 수 있습니다 (브라우저 는 값이 빈 문자열 인 경우 브라우저 가 최적화 될 수 있음 ).
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>
옵션 1 B : 지우기 textContent
- 위와 같이 사용하십시오
.textContent
. MDN에 따르면innerHTML
브라우저가 HTML 파서를 호출하지 않고 대신 요소의 모든 하위 요소를 단일#text
노드로 즉시 대체 할 때보 다 더 빠릅니다 .
doFoo.onclick = () => {
const myNode = document.getElementById("foo");
myNode.textContent = '';
}
<div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
<span>Hello</span>
</div>
<button id='doFoo'>Remove via textContent</button>
옵션 2 A : 모든 항목을 제거하기 위해 반복 lastChild
:
- 이 답변에 대한 이전 편집은 사용
firstChild
되었지만lastChild
컴퓨터 과학과 같이 사용하도록 업데이트되었지만 일반적 으로 컬렉션 의 마지막 요소 를 제거하는 것보다 컬렉션 의 마지막 요소 를 제거하는 것이 훨씬 빠릅니다 (컬렉션 구현 방법에 따라 다름) ). - 루프는 (예를 들어 요소 목록이 UA에 의해 직접 연결 목록으로 구현 된 경우) 보다 확인이 더 빠를
firstChild
경우를 대비 하여 계속 확인합니다 .firstChild
lastChild
doFoo.onclick = () => {
const myNode = document.getElementById("foo");
while (myNode.firstChild) {
myNode.removeChild(myNode.lastChild);
}
}
<div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
<span>Hello</span>
</div>
<button id='doFoo'>Remove via lastChild-loop</button>
옵션 2 B : 모든 항목을 제거하기 위해 반복 lastElementChild
:
- 이 접근 방식 은 부모의 모든 비
Element
(즉,#text
노드 및<!-- comments -->
) 자식 (자손은 아님)을 유지합니다. 이는 응용 프로그램 (예 : 인라인 HTML 주석을 사용하여 템플릿 명령을 저장하는 템플릿 시스템)에서 바람직 할 수 있습니다. - Internet Explorer
lastElementChild
는 IE9 에서만 지원을 추가했기 때문에이 방법은 최근까지 사용되지 않았습니다 .
doFoo.onclick = () => {
const myNode = document.getElementById("foo");
while (myNode.lastElementChild) {
myNode.removeChild(myNode.lastElementChild);
}
}
<div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
<!-- This comment won't be removed -->
<span>Hello <!-- This comment WILL be removed --></span>
<!-- But this one won't. -->
</div>
<button id='doFoo'>Remove via lastElementChild-loop</button>
보너스 : Element.clearChildren
원숭이 패치 :
Element
JavaScript 의 프로토 타입에 새로운 메소드 속성을 추가하여 HTML 요소 객체 가 있는el.clearChildren()
곳 으로 간단하게 호출 할 수 있습니다 .el
- 엄밀히 말하면 이것은 표준 DOM 기능이나 누락 된 기능이 아니기 때문에 폴리 필이 아닌 원숭이 패치입니다. 원숭이 패치는 많은 상황에서 올바르게 권장되지 않습니다.
if( typeof Element.prototype.clearChildren === 'undefined' ) {
Object.defineProperty(Element.prototype, 'clearChildren', {
configurable: true,
enumerable: false,
value: function() {
while(this.firstChild) this.removeChild(this.lastChild);
}
});
}
<div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
<span>Hello <!-- This comment WILL be removed --></span>
</div>
<button onclick="this.previousElementSibling.clearChildren()">Remove via monkey-patch</button>
답변
innerHTML
m93a가 올바르게 언급했듯이 현재 허용되는 답변은 (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의 “테스트 별 루프”는 종종 “반복마다”로 이해되며 첫 번째 반복 만 제거 할 노드가 있으므로 결과가 의미가 없습니다. 게시시이 스레드의 테스트가 잘못 설정되었습니다.
답변
최신 자바 스크립트를 remove
!
const parent = document.getElementById("foo");
while (parent.firstChild) {
parent.firstChild.remove();
}
이것은 ES5에서 노드 제거를 쓰는 새로운 방법입니다. 바닐라 JS이며 이전 버전보다 훨씬 잘 읽습니다 .
대부분의 사용자는 최신 브라우저를 가지고 있거나 필요한 경우 변환 할 수 있습니다.
브라우저 지원 -2019 년 12 월 95 %
답변
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에 대한 링크 를 제공 한 Andrey Lushnikov에게 감사합니다. (쿨 사이트!) .
편집 : 명확하게 말하면 Chrome에서 firstChild와 lastChild 사이의 성능 차이는 없습니다. 가장 좋은 대답은 성능에 대한 좋은 솔루션을 보여줍니다.
답변
자식이없는 노드 만 갖고 싶다면 다음과 같이 복사본을 만들 수도 있습니다.
var dupNode = document.getElementById("foo").cloneNode(false);
달성하려는 대상에 따라 다릅니다.