ลบองค์ประกอบลูกทั้งหมดของโหนด 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?

ฉันต้องการให้คำตอบตรงกับ DOM; แม้ว่าจะมีคะแนนพิเศษหากคุณให้คำตอบใน jQuery พร้อมกับคำตอบ DOM เท่านั้น


person Polaris878    schedule 17.10.2010    source แหล่งที่มา


คำตอบ (35)


ตัวเลือก 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 เช่นเดียวกับในวิทยาการคอมพิวเตอร์ โดยทั่วไป จะเร็วกว่ามากในการลบองค์ประกอบ สุดท้าย ของคอลเลกชัน มากกว่าที่จะลบองค์ประกอบแรก (ขึ้นอยู่กับวิธีการใช้งานคอลเลกชัน)
  • การวนซ้ำยังคงตรวจสอบ firstChild เผื่อไว้ จะตรวจสอบได้เร็วกว่า firstChild มากกว่า lastChild (เช่น หากรายการองค์ประกอบถูกนำมาใช้เป็นรายการลิงก์โดยตรงโดย UA)

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 แพทช์ลิง:

  • เราสามารถเพิ่ม method-property ใหม่ให้กับ Element ต้นแบบใน JavaScript เพื่อทำให้การเรียกใช้ง่ายขึ้นเหลือเพียง el.clearChildren() (โดยที่ el คืออ็อบเจ็กต์องค์ประกอบ HTML ใดๆ)
  • (พูดอย่างเคร่งครัดนี่คือ Monkey-Patch ไม่ใช่ Polyfill เนื่องจากนี่ไม่ใช่ฟีเจอร์ 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>

person Gabriel McAdams    schedule 17.10.2010
comment
  • ใช้เมธอด readLine() ของ java.io.BufferedReader เพื่ออ่านไฟล์ทีละบรรทัด
  • ใช้วิธี indexOf() ของ java.lang.String เพื่อค้นหาช่องว่างแรก
  • ใช้วิธี substring() ของ java.lang.String เพื่อแยกก่อนและหลังช่องว่าง
- person jottos; 21.11.2011
comment
@micha ฉันคิดว่าการทดสอบของคุณไม่ถูกต้อง ฉันได้เขียนอันของฉันบน jsfiddle (jsfiddle.net/6K6mv/5) และนี่คือผลลัพธ์ . ในขณะที่: 14ms; ภายในHTML: 7ms; เนื้อหาข้อความ: 7ms - person m93a; 02.02.2013
comment
@ m93a: การใช้ซอของคุณหลายครั้งทำให้ฉันได้ผลลัพธ์ทั่วทุกสถานที่ระหว่าง 6ms ถึง 11ms โดยพื้นฐานแล้วไม่ได้บอกอะไรฉันเลย ผลลัพธ์จะอยู่ใกล้กันมากกว่าความแปรปรวนเป็นมิลลิวินาทีระหว่างการทดสอบแต่ละครั้งสำหรับการทดสอบเดียวกัน สำหรับบันทึก: ไม่ใช่สคริปต์ของฉัน แต่เป็น jsperf.com ดูสิ่งนี้เพื่อความเข้าใจที่ดีขึ้นเกี่ยวกับผลการทดสอบ: stackoverflow.com/a/5262617/859877 และ stackoverflow.com/questions/4986245/how-does-jsperf-work/ - person micha; 03.02.2013
comment
@micha ใช่ฉันรู้ว่าผลการทดสอบหมายถึงอะไร แต่ดูเหมือนแปลก มันแสดงให้ฉันเห็นว่า innerHTML ช้าลง 98% - 99% และการทดสอบของฉันแสดงสิ่งที่ตรงกันข้าม แต่นี่ไม่ใช่การแชท ฉันกำลังออกจากการสนทนา - person m93a; 04.02.2013
comment
innerHTML ใช้งานได้เฉพาะเมื่อคุณจัดการกับ HTML เท่านั้น หากมีเช่น SVG ภายในการลบองค์ประกอบเท่านั้นที่จะใช้งานได้ - person stwissel; 27.03.2013
comment
ไม่เคย ไม่เคย ไม่เคยใช้ innerHTML = '' อย่า. ปัญหาคือดูเหมือนว่าไอเท็มจะถูกลบออกไป แต่ภายในโหนดยังคงอยู่และทำให้สิ่งต่าง ๆ ทำงานช้าลง คุณต้องลบแต่ละโหนดทั้งหมดด้วยเหตุผล ทดสอบทั้งใน Google Chrome และ IE โปรดพิจารณาลบโซลูชัน innerHTML เนื่องจากไม่ถูกต้อง - person Kenji; 21.09.2013
comment
@micha jsperf.com/innerhtml-vs-removechild/151 โดยใช้ .remove() เร็วขึ้นอีก - person Joeytje50; 11.02.2014
comment
@ joeytje50 เยี่ยมมาก! น่าเสียดายที่เป็น DOM4 และไม่มีให้บริการทุกที่ ฉันยังคงใช้ .removeChild() เพื่อความเข้ากันได้ที่ดีขึ้น นอกจากนี้ กำไรของ .remove() เป็นเพียง 2% เท่านั้น - person micha; 12.02.2014
comment
ฉันใส่สิ่งนี้ไว้ในต้นแบบเพื่อให้สามารถใช้งานได้ง่ายขึ้น: Element.prototype.clear = function(){ While (this.firstChild) {this.removeChild(this.firstChild);}} - person Abacus; 17.09.2014
comment
@Kenji - ถ้าฉันทำ document.documentElement.replaceChild(newBody, document.body) ล่ะ? องค์ประกอบเก่าๆ และเหตุการณ์ต่างๆ จะยังคงอยู่ในความทรงจำหรือไม่? (เมื่อเปลี่ยนองค์ประกอบทั้งตัว) - person vsync; 18.09.2014
comment
@Andrey Lushnikov: ขึ้นอยู่กับเบราว์เซอร์และเวอร์ชันใด ที่จริงแล้ว firstChild โดยรวมดีที่สุด: jsperf.com/innerhtml-vs-removechild/250 - person Stefan Steiger; 09.01.2015
comment
@vsync ฉันไม่เชื่อว่าความคิดเห็นของ Kenji นั้นมีรากฐานที่ดี การทำ innerHTML = '' นั้นช้าลง แต่ฉันไม่คิดว่าจะผิด การกล่าวอ้างเกี่ยวกับหน่วยความจำรั่วควรได้รับการสำรองข้อมูลพร้อมหลักฐาน - person Chris Middleton; 13.05.2015
comment
@Andrey Lushnikov firstChild และ LastChild ค่อนข้างเทียบเท่ากับ Chrome 43.0.2357.52 ของฉัน (การรันครั้งแรก RemoveChildFirst เร็วกว่าเล็กน้อย การรันครั้งที่สอง RemoveChildLast ชนะ) แต่ทั้งคู่เป็นผู้ชนะเหนือ innerHTML - person thdoan; 13.05.2015
comment
@Kenji แน่นอนว่าเบราว์เซอร์ฉลาดพอที่จะป้องกันหน่วยความจำรั่ว คุณจัดการเพื่อทำให้หน่วยความจำรั่วในเบราว์เซอร์หรือไม่? - person Pacerier; 03.06.2015
comment
ตัวอย่างของคุณไม่ผิด แต่ฉันคิดว่ามีกรณีที่ดีใน คำตอบนี้ ว่าการทดสอบ jsperf มีข้อบกพร่อง และ ไม่ได้วัดว่ามันควรจะเป็นอะไร (การอ้างสิทธิ์ในคำตอบที่เชื่อมโยงคือพวกเขาลบเฉพาะ div ที่ว่างเปล่า เนื่องจากพวกเขาสันนิษฐานอย่างผิดพลาดว่า DOM จะถูกเติมข้อมูลใหม่ระหว่างการทดสอบแต่ละครั้ง) กล่าวอีกนัยหนึ่ง innerHTML จะเร็วกว่า และมีวิธีการที่เร็วกว่านั้นอีก (การแทนที่โหนดด้วยว่าง อัน) เนื่องจากคำตอบของคุณได้รับการโหวตสนับสนุนอย่างมาก จึงคงจะดีถ้าคุณเปลี่ยนส่วนนั้นกลับ - person trlkly; 13.02.2016
comment
@Abacus ดำเนินการด้วยความระมัดระวังและตรวจสอบให้แน่ใจว่าเบราว์เซอร์ของกลุ่มเป้าหมายของคุณใช้งานได้ perfectionkills.com/whats-wrong-with-extending-the-dom - person gcampbell; 01.10.2016
comment
ฟังก์ชั่น EmptyElement (องค์ประกอบ) { var myNode = องค์ประกอบ; ในขณะที่ (myNode.firstChild) { myNode.removeChild (myNode.firstChild); } } องค์ประกอบที่ว่างเปล่า (document.body) - person Marian07; 19.10.2016
comment
(สมมติว่าเป็นจริง) คงจะดีถ้ามีเหตุผลในคำตอบ - person Old Badman Grey; 27.01.2017
comment
@chharvey คุณกำลังแก้ไขคอลเลกชันที่คุณกำลังวนซ้ำเมื่อคุณใช้ forEach ในลักษณะนั้น - person Jim Pedid; 03.03.2018
comment
นี่มันไร้สาระ เหตุใดประสิทธิภาพจึงมีความสำคัญที่นี่ มันคือ 120 fps หรือการทำงานแบบครั้งเดียว? - person Mars Robertson; 23.12.2018
comment
ฉันเห็นด้วยกับ @MichalStefanow ในกรณีนี้ ความเรียบง่ายของโค้ดควรมาก่อนประสิทธิภาพที่เพิ่มขึ้นขั้นต่ำ เว้นแต่ว่าคุณกำลังทำงานในสถานการณ์เฉพาะที่ต้องมีการปรับให้เหมาะสมอย่างพิถีพิถันในระดับนี้ มันจะไม่สร้างความแตกต่างเมื่อลบ 5-15 โหนด - person Felipe; 11.01.2019
comment
ในฐานะนักพัฒนาเว็บหน้าใหม่ แค่อยากบอกว่าท่านเป็นพระเจ้า ขอบคุณสำหรับทั้งสองวิธีครับ ฉันเล่นกับทั้งคู่แล้ว! - person Gutsygibbon; 03.02.2020
comment
remove ให้การวนซ้ำไม่สิ้นสุดสำหรับฉันใน Brave 80.1.5.123 removeChild ทำงานได้ดี - person OpenSauce; 07.05.2020
comment
หากฉันมีองค์ประกอบย่อย 10 องค์ประกอบที่ฉันต้องการลบและแต่ละองค์ประกอบมีเหตุการณ์แนบอยู่ ฉันควรลบเหตุการณ์ออกก่อนแล้วจึงแยกองค์ประกอบเอง หรือฉันไม่จำเป็นต้องลบเหตุการณ์ ฉันสามารถลบองค์ประกอบนั้นเองได้หรือไม่ (จาวาสคริปต์วานิลลา) - person JustANewCoder; 13.01.2021

คำตอบที่ยอมรับในปัจจุบันนั้นผิดเกี่ยวกับ 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 มักจะถูกเข้าใจว่าเป็น "ต่อการวนซ้ำ" และมีเพียงการวนซ้ำครั้งแรกเท่านั้นที่มีโหนดที่จะลบออก ดังนั้นผลลัพธ์จึงไม่มีความหมาย ในขณะที่โพสต์มีการทดสอบในชุดข้อความนี้ตั้งค่าไม่ถูกต้อง

person npjohns    schedule 09.04.2014
comment
jsperf ของคุณเสียอย่างสมบูรณ์ นั่นไม่ใช่หลักฐานที่ดีนัก - person bryc; 15.03.2015
comment
ขอขอบคุณที่ทราบว่า แก้ไขแล้ว insertBefore spec เปลี่ยน และไม่ใช้ undefin สำหรับพารามิเตอร์สุดท้ายอีกต่อไป - person npjohns; 28.04.2015
comment
นี่คือคำตอบที่ดีที่สุดในปัจจุบัน ทุกสิ่งทุกอย่างในชุดข้อความนี้เป็นข้อมูลที่บิดเบือน (!) ขอบคุณสำหรับการล้างการทดสอบเก่าที่ไม่ดีเหล่านั้นทั้งหมด - person Ben; 15.05.2015
comment
InnerHTML จะไม่ทำลายตัวจัดการเหตุการณ์ของคุณหรือทำให้การอ้างอิง jquery ใดๆ สับสน โดยจะทำให้ข้อมูลที่ถูกเก็บอยู่ใน jQuery.cache เสียหาย ส่งผลให้หน่วยความจำรั่วไหล เนื่องจากข้อมูลอ้างอิงเดียวที่พร้อมใช้งานในการจัดการข้อมูลนั้นอยู่ในองค์ประกอบที่คุณเพิ่งทำลาย - person ; 04.06.2016
comment
InnerHTML จะไม่ทำลายตัวจัดการเหตุการณ์ของคุณหรือทำให้การอ้างอิง jquery ใด ๆ ที่อ้างถึงคอนเทนเนอร์เสียหาย ไม่ใช่ลูก ๆ cloneNode ปิดคอนเทนเนอร์ ซึ่งหมายความว่าการอ้างอิงไปยังคอนเทนเนอร์จะไม่ได้รับการดูแล (jquery หรืออย่างอื่น) แคชของ Jquery อาจคุ้มค่าที่จะใช้ jquery เพื่อลบองค์ประกอบหากคุณมีข้อมูล jquery แนบอยู่ หวังว่าพวกเขาจะเปลี่ยนไปใช้ WeakMaps ในบางจุด . การทำความสะอาด (หรือแม้แต่การมีอยู่ของ) $.cache ดูเหมือนจะไม่ได้รับการบันทึกไว้อย่างเป็นทางการ - person npjohns; 04.06.2016
comment
jsperf ออฟไลน์ คุณช่วยอัปโหลดรหัสทดสอบที่นี่ ถ้าคุณมีหรือไม่ ฉันชื่นชมสิ่งนั้น! - person radl; 04.09.2016
comment
ฉันไม่มีรหัส แต่ jsperf อยู่ใน waybackmachine https://web.archive.org/web/20151008164028/http://jsperf.com/innerhtml-vs-removechild/300 - person npjohns; 07.09.2016
comment
เป็นเพียงแบบสอบถามแบบสุ่ม: เหตุใดเกณฑ์มาตรฐานของคุณจึงมีโค้ดสำหรับตั้งค่าข้อมูลที่จะถูกลบออกในส่วนที่มีการวัดประสิทธิภาพ แน่นอนว่าการตั้งค่าควรทำ นอก การวัดประสิทธิภาพ แต่การวัดประสิทธิภาพทั้งหมดของคุณเรียก refreshRange() (ซึ่งจะโคลนชุดข้อมูลการทดสอบลงในโหนดใหม่) จากภายในการทดสอบ คุณจะแน่ใจได้อย่างไรว่าสิ่งนี้ไม่บิดเบือนผลลัพธ์ - person Periata Breatta; 22.10.2016
comment
นอกจากนี้ เหตุใดคุณจึงใช้ contents().remove() ในการทดสอบ jquery ของคุณ (ซึ่งสร้างรายการภายในของโหนดลูกทั้งหมดแล้วลบออก) แทนที่จะเป็น empty() (ซึ่งเพิ่งลบออก) - person Periata Breatta; 22.10.2016
comment
ยังไม่ใช่มาตรฐาน imo ที่เหมาะสม ควรสร้างโหนดด้วยเหตุการณ์ คุณลักษณะ ฟังก์ชัน ฯลฯ ที่แนบมาด้วย เพื่อให้ได้เกณฑ์มาตรฐานที่สมจริงยิ่งขึ้น เป็นเรื่องที่สมเหตุสมผลที่ RemoveChild จะลบทรัพยากรที่แนบออกในขณะที่ InnerHTML อาจไม่เป็นเช่นนั้น ดังนั้นจึงช้าลง แต่หากคุณเปรียบเทียบโดยไม่มีทรัพยากรที่แนบมา ก็ไม่สมเหตุสมผล - person Gregoire D.; 12.01.2017
comment
@PeriataBreatta ความคิดเห็น jsperf หายไป แต่สิ่งที่ฉันอ้างถึงเกี่ยวกับความแตกหักคือการลบออกเพียงครั้งเดียวต่อการทดสอบ per-test-loop ของ Jsperf มักจะถูกเข้าใจว่าเป็นการวนซ้ำแต่ละครั้ง และมีเพียงการวนซ้ำครั้งแรกเท่านั้นที่จะได้ผล และผลลัพธ์ก็ไม่มีความหมาย เหมาะอย่างยิ่งที่จะตั้งค่านอกเหนือจากการวนซ้ำ แต่ตราบใดที่การตั้งค่าเหมือนกันและลดขนาดลง ผลลัพธ์ที่สัมพันธ์กันก็มีความหมาย ฉันไม่รู้เกี่ยวกับที่ว่างเปล่า () ขอบคุณสำหรับการแจ้งเตือน ฉันจะแก้ไข - person npjohns; 24.01.2017
comment
@GregoireD. คำถามนั้นไม่ได้มีการร้องขอข้อมูลนั้นจริงๆ และฉันคิดว่าข้อกังวลที่ใหญ่กว่าสำหรับการใช้งาน innerHTML ในการถอดโหนดอาจเป็นหน่วยความจำรั่วมากกว่าประสิทธิภาพ และการโยนหลักฐานการทดสอบที่รั่วใน jsperf ซึ่งไม่มีความสามารถในการทำความสะอาดต่อการวนซ้ำอาจเป็นไปได้ จบลงด้วยการบิดเบือนผลลัพธ์ - person npjohns; 24.01.2017
comment
การทดสอบ jsperf ใช้งานไม่ได้ที่นี่ โปรแกรมทดสอบรายงานสิ่งต่อไปนี้: ข้อผิดพลาด: โหนด Dom ไม่ได้สร้างขึ้นใหม่ในระหว่างการวนซ้ำ ผลการทดสอบจะไม่มีความหมาย - person senderle; 28.03.2017
comment
cloneNode(false) นั้นเร็วมากจริงๆ แต่ปัญหาคือเนื่องจากมันเป็นอันตราย คุณจะต้องอ้างอิงตัวแปรของคุณอีกครั้ง ซึ่งเป็นการลงโทษครั้งใหญ่ เช่น: jsperf.com/innerhtml-vs-removechild/467 - person thdoan; 14.02.2019
comment
ฉันกำลังศึกษาหลักสูตร DOM และเนื่องจากดูเหมือนว่า jsperf.com จะเป็นเมียหลวงและอาจใช้เวลานานพอสมควร ฉันจึงสร้างเพจบน jsben.ch. ณ วันนี้ innerHTML ยังคงเป็นผู้ชนะ ฉันใช้เวลากับ Rabbit Hole นี้มานานเกินไปแล้ว แต่ในปี 2020 ฉันต้องสงสัยว่าทำไมเรายังไม่มีวิธี .clear() หรือ .empty() DOM... - person Scott Means; 17.08.2020

ใช้ Javascript สมัยใหม่ด้วย remove!

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

นี่เป็นวิธีที่ใหม่กว่าในการเขียนการลบโหนดใน ES5 มันคือ vanilla JS และอ่านได้ มาก ดีกว่าการพึ่งพา parent

รองรับเบราว์เซอร์สมัยใหม่ทั้งหมด

การสนับสนุนเบราว์เซอร์ - 97% มิ.ย. 21

person Gibolt    schedule 15.11.2016
comment
for loop จะไม่ทำงานเนื่องจาก parent.children / parent.childNodes เป็นรายการสด การเรียกการลบจะแก้ไขรายการและผู้วนซ้ำของคุณจึงไม่รับประกันว่าจะวนซ้ำทุกสิ่ง ใน Chrome เช่น คุณจะข้ามโหนดอื่นๆ ไปทุกโหนด ควรใช้ while (parent.firstChild) { parent.removeChild(parent.firstChild); } วนซ้ำ developer.mozilla.org/en-US/docs/Web/ API/ParentNode/children developer.mozilla.org /en-US/docs/Web/API/Node/childNodes - person qix; 16.11.2016
comment
ชวเลขเจ๋งๆ แม้จะอ่านยาก: while (parent.firstChild && !parent.firstChild.remove()); - person Gibolt; 08.05.2017
comment
รายการเดียวเมื่อประสิทธิภาพไม่ใช่เรื่องใหญ่: [...parent.childNodes].forEach(el => el.remove()); - person ; 13.08.2018
comment
สิ่งนี้ใช้ไม่ได้ใน typescript... ให้ใช้ while (selectElem.firstElementChild) { selectElem.firstElementChild.remove(); } แทน - person John Henckel; 20.08.2018

อัปเดตปี 2020 - ใช้ replaceChildren() API!

ตอนนี้การแทนที่ลูกทั้งหมดสามารถทำได้ด้วย (รองรับเบราว์เซอร์ข้าม) แทนที่Children() API:

container.replaceChildren(...arrayOfNewChildren);

การดำเนินการนี้จะทำทั้งสองอย่าง: a) ลบรายการย่อยที่มีอยู่ทั้งหมด และ b) ผนวกรายการย่อยใหม่ที่กำหนดทั้งหมด ในการดำเนินการครั้งเดียว

คุณยังสามารถใช้ API เดียวกันนี้เพื่อลบรายการลูกที่มีอยู่โดยไม่ต้องแทนที่:

container.replaceChildren();

รองรับ Chrome/Edge 86+, Firefox 78+ และ Safari 14+ อย่างสมบูรณ์ (โปรดทราบว่าข้อมูล MDN ไม่ถูกต้องสำหรับ Safari ในขณะนี้) ระบุอย่างสมบูรณ์พฤติกรรม วิธีนี้น่าจะ เร็วกว่า กว่าวิธีอื่นๆ ที่เสนอที่นี่ เนื่องจากการถอดรายการลูกเก่าและการเพิ่มรายการลูกใหม่เสร็จสิ้นแล้ว a) โดยไม่ต้องใช้ innerHTML และ b) ในขั้นตอนเดียวแทนที่จะเป็นหลายรายการ

person Mason Freed    schedule 22.12.2020

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 ในการลบรายการลูก ข้อมูลนั้นจะยังคงอยู่

person user113716    schedule 17.10.2010
comment
วิธี innerHTML นั้นมีประสิทธิภาพมากที่สุด ที่กล่าวว่าข้อมูลถูกล้างโดย .empty() ของ jquery: กำจัด data() ภายใน jquery ที่เกี่ยวข้องกับแท็กลูกโดยใช้การวนซ้ำแบบเรียกซ้ำ (ช้า แต่อาจลดการใช้หน่วยความจำลงอย่างมาก) ป้องกันการรั่วไหลของหน่วยความจำหากคุณแนบเหตุการณ์โดยไม่ jquery เช่นการใช้ .onclick=... หากคุณไม่มีเหตุการณ์ดังกล่าวในรายการย่อยที่จะลบ การตั้งค่า innerHTML จะไม่รั่วไหล ดังนั้นคำตอบที่ดีที่สุดคือ - ขึ้นอยู่กับมัน - person Chris Moschini; 16.11.2011
comment
ทำไมไม่ใส่นิพจน์ firstChild ไว้ในเงื่อนไขของ while loop โดยตรงล่ะ? while ( myNode.firstChild ) { - person Victor Zamanian; 24.05.2016

หากคุณใช้ jQuery:

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

หากคุณไม่:

var foo = document.getElementById('foo');
while (foo.firstChild) foo.removeChild(foo.firstChild);
person PleaseStand    schedule 17.10.2010

ที่เร็วที่สุด...

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

ขอขอบคุณ Andrey Lushnikov สำหรับ ลิงก์ของเขาไปยัง jsperf.com (ไซต์เจ๋งๆ!)

แก้ไข: เพื่อให้ชัดเจน Chrome ไม่มีความแตกต่างด้านประสิทธิภาพระหว่าง firstChild และ LastChild คำตอบยอดนิยมแสดงวิธีแก้ปัญหาที่ดีสำหรับประสิทธิภาพ

person Gabe Halsmer    schedule 02.04.2013
comment
สิ่งเดียวกันโดยไม่มีคำเตือน LINT: clear: function ( container ) { for ( ; ; ) { var child = container.lastChild; ถ้า ( !child ) พัง; คอนเทนเนอร์removeChild( เด็ก ); } } - person cskwg; 03.01.2019

elm.replaceChildren()

เป็นการทดลองโดยไม่มีการสนับสนุนอย่างกว้างขวาง แต่เมื่อดำเนินการโดยไม่มีพารามิเตอร์จะทำสิ่งที่คุณต้องการ และมีประสิทธิภาพมากกว่าการวนซ้ำลูกแต่ละคนแล้วลบมันออก ดังที่ได้กล่าวไปแล้ว การแทนที่ innerHTML ด้วยสตริงว่างจะต้องมีการแยกวิเคราะห์ HTML ในส่วนของเบราว์เซอร์

เอกสารประกอบที่นี่

person Marc M.    schedule 28.07.2020
comment
สิ่งนี้ไม่มีประโยชน์สำหรับการสนับสนุนเบราว์เซอร์ล่าสุดเท่านั้น แต่อีกไม่กี่ปีข้างหน้า นี่จะเป็นหนทางไปอย่างแน่นอน ขอบคุณที่ชี้ให้เห็น - person leebickmtu; 16.10.2020
comment
caniuse.com/?search=replaceChildren Chrome และ Safari เวอร์ชันล่าสุดเพิ่งได้รับมา ให้เวลาสองสามเดือน พระเจ้า ฉันชอบการอัปเดตอัตโนมัติ - person Marc M.; 20.10.2020

หากคุณต้องการเพียงมีโหนดที่ไม่มีลูก คุณสามารถสร้างสำเนาของมันได้ดังนี้:

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

ขึ้นอยู่กับสิ่งที่คุณพยายามทำให้สำเร็จ

person DanMan    schedule 17.10.2010
comment
บางทีคุณอาจติดตามสิ่งนี้ด้วย parent.replaceChild(cloned, original) ก็ได้ นั่นอาจเร็วกว่าการลบลูกๆ ทีละรายการ และควรทำงานกับทุกสิ่งที่รองรับ DOM (เช่น เอกสาร XML ทุกประเภท รวมถึง SVG) การตั้งค่า innerHTML อาจเร็วกว่าการลบลูกๆ ทีละรายการ แต่จะไม่ทำงานกับสิ่งใดเลยนอกจากเอกสาร HTML ควรจะทดสอบสักครั้ง - person Maarten; 19.06.2012
comment
ที่จะไม่คัดลอกผู้ฟังเหตุการณ์ที่เพิ่มโดยใช้ addEventListener - person Matthew; 08.09.2012
comment
หากคุณสามารถใช้ชีวิตอยู่กับข้อจำกัดนั้นได้ มันก็รวดเร็วอย่างแน่นอน: jsperf.com/innerhtml-vs-removechild/ 137 - person DanMan; 01.02.2014

นี่เป็นอีกแนวทางหนึ่ง:

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();
}
person Nathan K    schedule 11.03.2014
comment
สิ่งนี้น่าสนใจ แต่ดูเหมือนค่อนข้างช้าเมื่อเทียบกับวิธีอื่น: jsperf.com/innerhtml-vs-removechild /256 - person Polaris878; 06.01.2015

element.textContent = '';

มันเหมือนกับ InnerText ยกเว้นมาตรฐาน ช้ากว่าเล็กน้อยกว่า removeChild() แต่ใช้งานง่ายกว่าและจะไม่สร้างความแตกต่างด้านประสิทธิภาพมากนักหากคุณไม่' ไม่มีสิ่งที่จะลบมากเกินไป

person bjb568    schedule 28.03.2014
comment
โหนดข้อความไม่ใช่องค์ประกอบ - person check_ca; 23.04.2014
comment
ขออภัยคุณพูดถูก มันจะลบองค์ประกอบลูกทั้งหมดออกจริงๆ - person check_ca; 25.04.2014
comment
สิ่งนี้ใช้ไม่ได้กับ Internet Explorer เวอร์ชันเก่า - person pwdst; 29.03.2017

นี่คือสิ่งที่ฉันมักจะทำ:

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

และต่อมาคุณสามารถล้างองค์ประกอบ dom ใด ๆ ด้วย:

anyDom.empty()
person Ado Ren    schedule 09.09.2018
comment
ฉันชอบวิธีแก้ปัญหานี้! มีเหตุผลใดที่ฉันควรใช้สิ่งนี้เพื่อตั้งค่า innerHTML เป็นสตริงว่าง - person Vim Diesel; 26.10.2019
comment
ประสิทธิภาพการทำงาน : domEl.innerHTML = "" แย่และถือว่าเป็นการปฏิบัติที่ไม่ดี - person Ado Ren; 27.10.2019

Ecma6 ช่วยให้ใช้งานได้ง่ายและกะทัดรัด

myNode.querySelectorAll('*').forEach( n => n.remove() );

นี่เป็นการตอบคำถาม และ ลบ “โหนดย่อยทั้งหมด”

หากมีโหนดข้อความที่เป็นของ myNode ไม่สามารถเลือกได้ด้วยตัวเลือก CSS ในกรณีนี้ เราต้องใช้ (เช่น):

myNode.textContent = '';

อันที่จริงอันสุดท้ายอาจเป็นวิธีแก้ปัญหาที่เร็วและมีประสิทธิภาพมากกว่า

.textContent มีประสิทธิภาพมากกว่า .innerText และ .innerHTML โปรดดู: MDN

person Marco Balestra    schedule 12.11.2020

เพื่อตอบสนองต่อ 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 );

นอกจากนี้ยังใช้ได้กับโหนดที่ไม่ได้อยู่ใน dom ซึ่งส่งคืนค่าว่างเมื่อพยายามเข้าถึง 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 );

ฉันพบว่าวิธีนี้มีประโยชน์มากเมื่อแทนที่สตริงภายในองค์ประกอบ หากคุณไม่แน่ใจว่าโหนดจะมีอะไรบ้าง แทนที่จะกังวลว่าจะทำความสะอาดอย่างไร ให้เริ่มต้นใหม่

person jeroen    schedule 15.03.2013
comment
สิ่งที่เลวร้ายที่สุดที่เคยมีมา หากคุณกำลังแทนที่โหนดดั้งเดิมด้วยโคลน คุณจะสูญเสียการอ้างอิงไปยังโหนดดั้งเดิม ไม่มีตัวจัดการเหตุการณ์และการผูกอื่นๆ จะไม่ทำงาน - person Arun Aravind; 07.12.2013

การใช้ range loop ให้ความรู้สึกเป็นธรรมชาติที่สุดสำหรับฉัน:

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

จากการวัดของฉันใน Chrome และ Firefox มันช้ากว่าประมาณ 1.3 เท่า ในสถานการณ์ปกติสิ่งนี้อาจจะไม่สำคัญ

person emu    schedule 06.12.2018

มีสองทางเลือกในการบรรลุเป้าหมายดังกล่าว:

ที่เร็วที่สุด ():

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

ทางเลือก (ช้ากว่า):

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

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

เกณฑ์มาตรฐานพร้อมตัวเลือกที่แนะนำ

person magiccrafter    schedule 27.01.2017

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

การดำเนินการนี้จะลบโหนดทั้งหมดภายในองค์ประกอบ

person Henrik    schedule 01.02.2014
comment
...เพราะมันซับซ้อนโดยไม่จำเป็น และไม่มีคำอธิบายเกี่ยวกับวิธีการทำงาน (ซึ่งจริงๆ แล้วไม่ชัดเจน) ฉันสงสัย - person Periata Breatta; 23.10.2016

InnerText เป็นผู้ชนะ! http://jsperf.com/innerhtml-vs-removechild/133 ในการทดสอบก่อนหน้านี้ทั้งหมด dom ภายในของโหนดพาเรนต์ถูกลบในการวนซ้ำครั้งแรก จากนั้นจึงลบ InnerHTML หรือ RemoveChild โดยที่นำไปใช้กับ div ว่าง

person Alexey    schedule 27.01.2014
comment
innerText เป็นสิ่งที่ MS ที่เป็นกรรมสิทธิ์ แค่พูด. - person DanMan; 01.02.2014
comment
ค่อนข้างแน่ใจว่านี่เป็นการทดสอบที่มีข้อบกพร่อง - ขึ้นอยู่กับ box ที่ไม่พร้อมใช้งานในรูปแบบ var แต่ผ่านการค้นหา DOM ตาม id และเนื่องจากการวนซ้ำ while ทำให้การโทรช้านี้หลายครั้งจึงถูกลงโทษ - person nrabinowitz; 10.12.2015

วิธีที่ง่ายที่สุดในการลบโหนดย่อยของโหนดผ่าน Javascript

var myNode = document.getElementById("foo");
while(myNode.hasChildNodes())
{
   myNode.removeChild(myNode.lastChild);
}
person Chaitanya Bapat    schedule 18.07.2016

ฉันเห็นคนทำ:

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 ทันที!

person Noitidart    schedule 03.02.2014
comment
ฉันคิดว่าจะเร็วที่สุดหรือไม่ การทดสอบ jsperf บางอย่างสามารถพิสูจน์ได้ทั้งสองกรณี - person Nikos M.; 06.10.2014
comment
เยี่ยมมาก ขอบคุณสำหรับการทดสอบเหล่านั้น พวกเขาไม่ได้รวม for (var i=0... หนึ่งไว้ด้วย แต่นี่คือสิ่งที่ฉันได้รับเมื่อทำการทดสอบ: i.imgur.com/Mn61AmI.png ดังนั้นในการทดสอบทั้งสามครั้งนั้น FirstNode จึงเร็วกว่า LastNode และ InnerHTML ซึ่งเจ๋งมาก - person Noitidart; 06.10.2014
comment
ฉันเพิ่มการทดสอบ: jsperf.com/innerhtml-vs-removechild/220 สิ่งที่น่าสนใจ การทำวิธี el.firstNode เป็นวิธีที่เร็วที่สุด - person Noitidart; 06.10.2014

โดยทั่วไป JavaScript จะใช้อาร์เรย์เพื่ออ้างอิงรายการของโหนด DOM ดังนั้น วิธีนี้จะทำงานได้ดีหากคุณสนใจที่จะทำผ่านอาร์เรย์ HTMLElements นอกจากนี้ ที่น่าสังเกตก็คือ เนื่องจากฉันใช้การอ้างอิงอาร์เรย์แทน JavaScript โปรโต สิ่งนี้จึงควรใช้ได้กับเบราว์เซอร์ใดก็ได้ รวมถึง IE

while(nodeArray.length !== 0) {
  nodeArray[0].parentNode.removeChild(nodeArray[0]);
}
person r00t hkr    schedule 13.07.2017

ทำไมเราไม่ทำตามวิธีที่ง่ายที่สุดที่นี่ "remove" วนซ้ำอยู่ข้างใน

const foo = document.querySelector(".foo");
while (foo.firstChild) {
  foo.firstChild.remove();     
}
  • การเลือก div ระดับบนสุด
  • การใช้เมธอด "remove" ภายใน While loop เพื่อกำจัดองค์ประกอบลูกแรก จนกระทั่งไม่เหลือเลย
person Neelansh Verma    schedule 21.05.2018
comment
โปรดอธิบายบรรทัดโค้ดของคุณเพื่อให้ผู้ใช้รายอื่นเข้าใจฟังก์ชันการทำงานของโค้ดได้ ขอบคุณ! - person Ignacio Ara; 21.05.2018
comment
@IgnacioAra เสร็จแล้ว! - person Neelansh Verma; 21.05.2018

เพิ่งเห็นมีคนพูดถึงคำถามนี้ในอีกเรื่องหนึ่งและคิดว่าฉันจะเพิ่มวิธีที่ฉันยังไม่เห็น:

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

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

ฟังก์ชั่นที่ชัดเจนกำลังรับองค์ประกอบและใช้โหนดพาเรนต์เพื่อแทนที่ตัวเองด้วยการคัดลอกโดยไม่มีลูก ประสิทธิภาพจะไม่เพิ่มขึ้นมากนักหากองค์ประกอบกระจัดกระจาย แต่เมื่อองค์ประกอบมีโหนดจำนวนมาก ประสิทธิภาพจะเพิ่มขึ้น

person Harry Chilinguerian    schedule 14.11.2018
comment
จริงๆ แล้วดูเหมือนว่าจะมีการกล่าวถึงที่นี่ stackoverflow.com/a/15441725/576767 - person Félix Adriyel Gagnon-Grenier; 16.11.2018
comment
เฟลิกซ์ ฉันคงพลาดไปแล้ว ขอบคุณสำหรับการแก้ไข +1 - person Harry Chilinguerian; 19.11.2018

แนวทางการทำงานเท่านั้น:

const domChildren = (el) => Array.from(el.childNodes)
const domRemove = (el) => el.parentNode.removeChild(el)
const domEmpty = (el) => domChildren(el).map(domRemove)

"childNodes" ใน domChildren จะให้ nodeList ขององค์ประกอบชายด์ทันที ซึ่งจะว่างเปล่าเมื่อไม่พบ เพื่อที่จะแมปบน nodeList นั้น domChildren จะแปลงเป็นอาร์เรย์ domEmpty จับคู่ฟังก์ชัน domRemove กับองค์ประกอบทั้งหมดที่ลบออก

ตัวอย่างการใช้งาน:

domEmpty(document.body)

ลบเด็กทั้งหมดออกจากองค์ประกอบร่างกาย

person Dolph Roger    schedule 10.12.2019

คุณสามารถลบองค์ประกอบย่อยทั้งหมดออกจากคอนเทนเนอร์ได้ดังนี้:

function emptyDom(selector){
 const elem = document.querySelector(selector);
 if(elem) elem.innerHTML = "";
}

ตอนนี้คุณสามารถเรียกใช้ฟังก์ชันและส่งตัวเลือกดังนี้:

หากองค์ประกอบมี id = foo

emptyDom('#foo');

หากองค์ประกอบมีคลาส = foo

emptyDom('.foo');

ถ้าองค์ประกอบมี tag = ‹div

emptyDom('div')
person harish kumar    schedule 11.07.2020

element.innerHTML = "" (หรือ .textContent) คือ โดยมาก วิธีแก้ปัญหาที่เร็วที่สุด

คำตอบส่วนใหญ่ที่นี่มาจากการทดสอบที่มีข้อบกพร่อง

ตัวอย่างเช่น: https://jsperf.com/innerhtml-vs-removechild/15
การทดสอบนี้ไม่ได้เพิ่มลูกใหม่ให้กับองค์ประกอบระหว่างการวนซ้ำแต่ละครั้ง การวนซ้ำครั้งแรกจะลบเนื้อหาขององค์ประกอบ และการวนซ้ำอื่นๆ จะไม่ทำอะไรเลย ในกรณีนี้ while (box.lastChild) box.removeChild(box.lastChild) เร็วกว่าเนื่องจาก box.lastChild คือ null 99% ของเวลา

นี่คือการทดสอบที่เหมาะสม: https://jsperf.com/innerhtml-conspiracy

สุดท้าย อย่า ใช้ node.parentNode.replaceChild(node.cloneNode(false), node) สิ่งนี้จะแทนที่โหนดด้วยสำเนาของตัวเองโดยไม่มีลูก อย่างไรก็ตาม สิ่งนี้จะไม่รักษาผู้ฟังเหตุการณ์และทำลายการอ้างอิงอื่น ๆ ไปยังโหนด

person 12Me21    schedule 05.08.2020

หากคุณต้องการล้างข้อมูลพาเรนต์ทั้งหมด DOM ก็ง่ายมาก...

เพียงใช้ .empty()

function removeAll() {
  $('#parent').empty();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button onclick="removeAll()">Remove all the element of parent</button>
<div id="parent">
  <h3>Title</h3>
  <p>Child 1</p>
  <p>Child 2</p>
  <p>Child 3</p>
</div>

person Rohit Tagadiya    schedule 22.04.2021

เพียงแค่ IE เท่านั้น:

parentElement.removeNode(true);

true - หมายถึงการลบออกอย่างล้ำลึก - ซึ่งหมายความว่ารายการย่อยทั้งหมดจะถูกลบออกด้วย

person user2656596    schedule 15.12.2016
comment
เช่น? นี่คือศตวรรษที่ 21! - person everlasto; 29.11.2017

วิธีที่ง่ายที่สุด:

let container = document.getElementById("containerId");
container.innerHTML = "";
person milosz    schedule 05.02.2018
comment
แม้ว่าจะใช้งานได้ แต่ระวังว่า container.innerHTML = null จะทำให้ Internet Explorer แสดงข้อความ null ฉันว่านี่ไม่ได้ทำให้เด็ก ๆ หายไปเลย - person Arjan; 26.03.2018

ง่ายและรวดเร็วโดยใช้ for loop!!

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

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

สิ่งนี้จะไม่ทำงานในแท็ก <span>!

person Mohit Karkar    schedule 18.08.2018
comment
เหนือสิ่งอื่นใดวิธีแก้ปัญหาไม่มีโค้ดใดลบแท็ก <span> - person Mohit Karkar; 18.08.2018

วิธีอื่นใน jQuery

var foo = $("#foo");
foo.children().remove();
//or
$("*", foo ).remove();
//or
foo.html("");
//or
foo.empty();
person Anoop    schedule 16.10.2011
comment
โหวตลงเพราะ OP กล่าวว่าคำตอบใน DOM แบบตรงเป็นที่ต้องการ - person bwindels; 01.06.2015
comment
นอกจากนี้ jQuery ยังมีวิธี .empty() แค่ $("#foo").empty() ก็เพียงพอแล้ว - person YakovL; 06.08.2018

หากคุณต้องการใส่บางสิ่งกลับเข้าไปใน 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

person Bjathr    schedule 18.10.2017

นี่เป็นจาวาสคริปต์ล้วนๆ ฉันไม่ได้ใช้ 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 ="";

})
person Ir Calif    schedule 30.03.2017

ด้วย jQuery :

$("#foo").find("*").remove();
person Arnaud F.    schedule 17.10.2010
comment
$('#foo').children().remove() มีเหตุผลมากกว่ามาก - person Krzysztof Dąbrowski; 08.03.2017

person    schedule
comment
มันอธิบายตนเอง - person Alien; 09.05.2020