Bagaimana cara saya menghapus semua elemen turunan dari simpul DOM dalam JavaScript?
Katakanlah saya memiliki HTML (jelek) berikut:
<p id="foo">
<span>hello</span>
<div>world</div>
</p>
Dan saya ambil simpul yang saya inginkan seperti ini:
var myNode = document.getElementById("foo");
Bagaimana saya bisa menghapus anak-anak foo
sehingga hanya <p id="foo"></p>
tersisa?
Bisakah saya lakukan:
myNode.childNodes = new Array();
atau haruskah saya menggunakan kombinasi removeElement
?
Saya ingin jawabannya langsung DOM; meskipun poin tambahan jika Anda juga memberikan jawaban di jQuery bersama dengan jawaban DOM-only.
javascript
dom
Polaris878
sumber
sumber
innerHTML = ''
lebih lambat, tapi saya pikir itu tidak "salah". Setiap klaim kebocoran memori harus didukung dengan bukti.Jawaban yang saat ini diterima salah tentang
innerHTML
menjadi lebih lambat (setidaknya di IE dan Chrome), seperti yang disebutkan dengan benar m93a.Chrome dan FF secara dramatis lebih cepat menggunakan metode ini (yang akan menghancurkan data jquery terlampir):
dalam beberapa detik untuk FF dan Chrome, dan tercepat di IE:
InnerHTML tidak akan memusnahkan event handler Anda atau menghancurkan referensi jquery , juga direkomendasikan sebagai solusi di sini: https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML .
Metode manipulasi DOM tercepat (masih lebih lambat dari dua sebelumnya) adalah penghapusan Rentang, tetapi rentang tidak didukung sampai IE9.
Metode lain yang disebutkan tampaknya sebanding, tetapi jauh lebih lambat daripada innerHTML, kecuali untuk outlier, jquery (1.1.1 dan 3.1.1), yang jauh lebih lambat dari yang lain:
Bukti di sini:
http://jsperf.com/innerhtml-vs-removechild/167http://jsperf.com/innerhtml-vs-removechild/300https://jsperf.com/remove-all-child-elements-of-a- dom-node-in-javascript (URL baru untuk reboot jsperf karena mengedit URL lama tidak berfungsi)"Per-test-loop" Jsperf sering dipahami sebagai "per-iterasi", dan hanya iterasi pertama yang memiliki node untuk dihapus sehingga hasilnya tidak berarti, pada saat memposting ada tes di utas ini yang dibuat secara tidak benar.
sumber
jQuery.cache
, menyebabkan kebocoran memori karena satu-satunya referensi yang tersedia untuk mengelola data itu adalah pada elemen yang baru saja Anda hancurkan.cloneNode
mengganti wadah, yang berarti referensi ke wadah tidak dipertahankan (jquery atau lainnya). Tembolok Jquery mungkin membuatnya layak menggunakan jquery untuk menghapus elemen jika Anda memiliki data jquery terlampir. Semoga mereka beralih ke WeakMaps di beberapa titik. Membersihkan (atau bahkan keberadaan) $ .cache tampaknya tidak didokumentasikan secara resmi.Gunakan Javascript modern, dengan
remove
!Ini adalah cara yang lebih baru untuk menulis penghapusan node di ES5. Ini adalah vanilla JS dan jauh lebih bagus daripada versi sebelumnya.
Sebagian besar pengguna harus memiliki peramban modern atau Anda dapat melakukan transpile turun jika diperlukan.
Dukungan Browser - 95% Des 2019
sumber
while (parent.firstChild) { parent.removeChild(parent.firstChild); }
loop. developer.mozilla.org/en-US/docs/Web/API/ParentNode/children developer.mozilla.org/en-US/docs/Web/API/Node/childNodeswhile (parent.firstChild && !parent.firstChild.remove());
[...parent.childNodes].forEach(el => el.remove());
while (selectElem.firstElementChild) { selectElem.firstElementChild.remove(); }
Jika ada kemungkinan Anda memiliki keturunan yang terpengaruh jQuery, maka Anda harus menggunakan beberapa metode yang akan membersihkan data jQuery.
.empty()
Metode jQuery akan memastikan bahwa data apa pun yang terkait dengan jQuery dengan elemen yang dihapus akan dibersihkan.Jika Anda hanya menggunakan
DOM
metode menghapus anak-anak, data itu akan tetap ada.sumber
while ( myNode.firstChild ) {
while(fc = myNode.firstChild){ myNode.removeChild(fc); }
Jika Anda menggunakan jQuery:
Jika tidak:
sumber
Tercepat...
Terima kasih kepada Andrey Lushnikov untuk tautannya ke jsperf.com (situs keren!).
EDIT: untuk menjadi jelas, tidak ada perbedaan kinerja di Chrome antara firstChild dan lastChild. Jawaban teratas menunjukkan solusi yang baik untuk kinerja.
sumber
Jika Anda hanya ingin memiliki simpul tanpa anak-anaknya, Anda juga dapat membuat salinannya seperti ini:
Tergantung pada apa yang ingin Anda capai.
sumber
parent.replaceChild(cloned, original)
? Itu mungkin lebih cepat daripada menghapus anak satu per satu dan harus bekerja pada semua yang mendukung DOM (jadi setiap jenis dokumen XML, termasuk SVG). Mengatur innerHTML mungkin juga lebih cepat daripada menghapus anak satu per satu, tetapi itu tidak berfungsi apa-apa selain dokumen HTML. Harus menguji itu beberapa waktu.addEventListener
.Inilah pendekatan lain:
sumber
Ini seperti innerText, kecuali standar. Ini sedikit lebih lambat daripada
removeChild()
, tetapi lebih mudah digunakan dan tidak akan membuat banyak perbedaan kinerja jika Anda tidak memiliki terlalu banyak hal untuk dihapus.sumber
Menanggapi DanMan, Maarten dan Matt. Mengkloning sebuah node, untuk mengatur teks memang cara yang layak dalam hasil saya.
Ini juga berfungsi untuk node tidak di dom yang mengembalikan null ketika mencoba mengakses parentNode. Selain itu, jika Anda perlu aman, sebuah node kosong sebelum menambahkan konten, ini sangat membantu. Pertimbangkan use case di bawahnya.
Saya menemukan metode ini sangat berguna ketika mengganti string di dalam elemen, jika Anda tidak yakin apa yang akan mengandung node, daripada khawatir bagaimana membersihkan kekacauan, mulailah dengan segar.
sumber
Inilah yang biasanya saya lakukan:
Dan voila, nanti Anda dapat mengosongkan elemen dom dengan:
sumber
domEl.innerHTML = ""
buruk dan dianggap praktik burukAda beberapa opsi untuk mencapai itu:
Tercepat ():
Alternatif (lebih lambat):
Benchmark dengan opsi yang disarankan
sumber
Ini akan menghapus semua node dalam elemen.
sumber
innerText adalah pemenangnya! http://jsperf.com/innerhtml-vs-removechild/133 . Pada semua tes sebelumnya, dom dom dari simpul orangtua dihapus pada iterasi pertama dan kemudian innerHTML atau removeChild di mana diterapkan pada div kosong.
sumber
innerText
adalah hak milik MS. Hanya mengatakan.box
tersedia bukan sebagai var tetapi melalui pencarian DOM berdasarkan id, dan karenawhile
loop membuat panggilan lambat ini berkali-kali itu dihukum.Cara termudah untuk menghapus simpul anak dari sebuah simpul melalui Javascript
sumber
saya melihat orang melakukan:
lalu seseorang berkata menggunakan
el.lastNode
lebih cepatnamun saya akan berpikir bahwa ini yang tercepat:
Bagaimana menurut anda?
ps: topik ini adalah penyelamat bagi saya. addon firefox saya ditolak karena saya menggunakan innerHTML. Sudah kebiasaan untuk waktu yang lama. maka saya foudn ini. dan saya benar-benar memperhatikan perbedaan kecepatan. saat memuat, innerhtml perlu beberapa saat untuk memperbarui, namun dengan addElement instan!
sumber
for (var i=0...
. Tapi inilah yang saya dapatkan ketika saya menjalankan tes-tes tersebut: i.imgur.com/Mn61AmI.png sehingga dalam ketiga tes tersebut firstNode lebih cepat daripada lastNode dan innerHTML yang benar-benar kerenMenggunakan rentang loop terasa paling alami bagi saya:
Menurut pengukuran saya di Chrome dan Firefox, ini sekitar 1.3x lebih lambat. Dalam keadaan normal, ini mungkin tidak masalah.
sumber
sumber
Secara umum, JavaScript menggunakan array untuk referensi daftar node DOM. Jadi, ini akan berfungsi dengan baik jika Anda memiliki minat untuk melakukannya melalui array HTMLElements. Juga, patut dicatat, karena saya menggunakan referensi array bukan JavaScript proto, ini harus bekerja di browser apa pun, termasuk IE.
sumber
Mengapa kita tidak mengikuti metode paling sederhana di sini "hapus" di dalam sementara.
sumber
Hanya melihat seseorang menyebutkan pertanyaan ini di yang lain dan berpikir saya akan menambahkan metode yang belum saya lihat:
Fungsi yang jelas adalah mengambil elemen dan menggunakan simpul orangtua untuk mengganti sendiri dengan salinan tanpa anak-anak itu. Tidak banyak peningkatan kinerja jika elemen jarang tetapi ketika elemen memiliki banyak node, keuntungan kinerja direalisasikan.
sumber
Pendekatan hanya fungsional:
"childNodes" di domChildren akan memberikan nodeList dari elemen anak-anak langsung, yang kosong ketika tidak ada yang ditemukan. Untuk memetakan melalui nodeList, domChildren mengubahnya menjadi array. domEmpty memetakan fungsi domRemove atas semua elemen yang menghapusnya.
Contoh penggunaan:
menghapus semua anak dari elemen tubuh.
sumber
Cara lain di jQuery
sumber
.empty()
metode, hanya$("#foo").empty()
akan cukupcukup hanya IE:
true
- Berarti untuk melakukan deep removal - yang berarti bahwa semua anak juga dihapussumber
Cara termudah:
sumber
container.innerHTML = null
akan membuat Internet Explorer menampilkan teksnull
. Jadi, ini tidak benar-benar menghapus anak-anak, kataku.sederhana dan cepat digunakan untuk loop !!
ini tidak akan berfungsi dalam
<span>
tag!sumber
<span>
tagJika Anda ingin memasukkan sesuatu ke dalamnya
div
,innerHTML
itu mungkin lebih baik.Contoh saya:
Jika saya menggunakan metode
.firstChild
atau fungsi tidak bekerja setelahnya, tetapi tidak ada masalah dengan metode tersebut..lastChild
displayHTML()
.innerHTML
sumber
Ini adalah javascript murni saya tidak menggunakan jQuery tetapi bekerja di semua browser bahkan IE dan sangat mudah dimengerti
sumber
dengan jQuery:
sumber
$('#foo').children().remove()
jauh lebih logis