Saya bertanya-tanya, JavaScript menawarkan berbagai metode untuk mendapatkan elemen anak pertama dari elemen apa pun, tetapi mana yang terbaik? Maksud saya, sebagian besar browser yang kompatibel, tercepat, terlengkap, dan dapat diprediksi dalam hal perilaku. Daftar metode / properti yang saya gunakan sebagai alias:
var elem = document.getElementById('container');
var child = elem.children[0];
var child = elem.firstElementChild; // == children[0]
Ini berfungsi untuk kedua kasus:
var child = elem.childNodes[0]; // or childNodes[1], see below
Itu dalam hal bentuk, atau <div>
iterasi. Jika saya mungkin menemukan elemen teks:
var child = elem.childNodes; // treat as NodeList
var child = elem.firstChild;
Sejauh yang saya bisa, firstChild
gunakan NodeList dari childNodes
, dan firstElementChild
gunakan children
. Saya mendasarkan asumsi ini pada referensi MDN:
childNode
adalah referensi ke elemen anak pertama dari simpul elemen, ataunull
jika tidak ada.
Saya menduga bahwa, dalam hal kecepatan, perbedaannya, jika ada, akan hampir tidak ada, karena firstElementChild
secara efektif referensi children[0]
, dan children
objek sudah ada dalam memori pula.
Apa yang melemparku, adalah childNodes
objeknya. Saya telah menggunakannya untuk melihat formulir, di elemen tabel. Sementara children
daftar semua elemen bentuk, childNodes
juga tampaknya termasuk spasi dari kode HTML:
console.log(elem.childNodes[0]);
console.log(elem.firstChild);
Keduanya log <TextNode textContent="\n ">
console.log(elem.childNodes[1]);
console.log(elem.children[0]);
console.log(elem.firstElementChild);
Semua log <input type="text"
... >
. Bagaimana bisa? Saya mengerti bahwa satu objek akan memungkinkan saya untuk bekerja dengan kode HTML "mentah", sementara yang lain menempel pada DOM, tetapi childNodes
elemen tampaknya bekerja di kedua level.
Untuk kembali ke pertanyaan awal saya, tebakan saya adalah: jika saya ingin objek yang paling komprehensif, childNodes
adalah cara untuk pergi, tetapi karena kelengkapannya, itu mungkin bukan yang paling dapat diprediksi dalam hal mengembalikan elemen yang saya inginkan / harapkan pada saat tertentu. Dukungan lintas-browser mungkin juga terbukti menjadi tantangan dalam kasus itu, meskipun saya bisa saja salah.
Adakah yang bisa menjelaskan perbedaan antara benda-benda yang ada? Jika ada perbedaan kecepatan, betapapun bisa diabaikan, saya juga ingin tahu. Jika saya melihat ini semua salah, jangan ragu untuk mendidik saya.
PS: Tolong, saya suka JavaScript, jadi ya, saya mau berurusan dengan hal semacam ini. Jawaban seperti "penawaran jQuery dengan ini untuk Anda" bukan yang saya cari, karenanya tidakjquery menandai.
sumber
Jawaban:
Sepertinya Anda terlalu memikirkannya. Anda telah mengamati perbedaan antara
childNodes
danchildren
, yangchildNodes
berisi semua simpul, termasuk simpul teks yang seluruhnya terdiri dari spasi, sedangkanchildren
kumpulan hanya simpul anak yang merupakan elemen. Hanya itu yang ada di sana.Tidak ada yang tak terduga tentang koleksi mana pun, meskipun ada beberapa masalah yang harus diperhatikan:
childNodes
sementara browser lain melakukannyachildren
sementara browser lain hanya memiliki elemenchildren
,firstElementChild
dan teman hanyalah kenyamanan, menghadirkan tampilan DOM yang disaring terbatas pada elemen adil.sumber
<td\n\t>content</td>
. Seperti yang mungkin Anda lakukan dengan XML, untuk menghindari spasi kosong dianggap sebagai bagian dari data (atau DOM, dalam hal ini). Mengapa spasi putih di dalam tag dimasukkan dalam DOM?children
berasal dari IE 4 lebih dari satu dekade sebelum menjadi standar atau diadopsi oleh browser lain, Anda bisa berpendapat bahwa IE <= 8 benar dan browser lain salah.firstElementChild mungkin tidak tersedia di IE <9 (hanya firstChild)
pada IE <9 firstChild adalah firstElementChild karena MS DOM (IE <9) tidak menyimpan node teks kosong. Tetapi jika Anda melakukannya di browser lain, mereka akan mengembalikan node teks kosong ...
solusi saya
child=(elem.firstElementChild||elem.firstChild)
ini akan memberikan anak pertama bahkan pada IE <9
sumber
elem.firstChild
bukan elemen node, hasilnya akan berbeda di IE lama, karenaelem.firstElementChild
selalu elemen node.firstElementChild
juga tidak selalu aman di browser non-IE: Firefox hanya mulai mendukungnya dalam versi 3.5.Cara lintas browser yang harus dilakukan adalah menggunakan
childNodes
untuk mendapatkanNodeList
, lalu membuat array semua node dengannodeType
ELEMENT_NODE .http://jsfiddle.net/s4kxnahu/
Ini sangat mudah jika Anda menggunakan perpustakaan utilitas seperti lodash :
Masa depan:
Anda dapat menggunakan
querySelectorAll
dalam kombinasi dengan:scope
pseudo-class (cocok dengan elemen yang merupakan titik referensi pemilih):Pada saat penulisan ini
:scope
didukung di Chrome, Firefox dan Safari.sumber
Hanya untuk menambah jawaban lain, masih ada perbedaan yang patut diperhatikan di sini, khususnya ketika berhadapan dengan
<svg>
elemen.Saya telah menggunakan keduanya
.childNodes
dan.children
lebih suka bekerja dengan yangHTMLCollection
disampaikan oleh.children
pengambil.Namun hari ini, saya mengalami masalah dengan IE / Edge gagal saat digunakan
.children
pada Windows Vista<svg>
. Meskipun.children
didukung di IE pada elemen HTML dasar, itu tidak didukung pada dokumen / fragmen dokumen, atau elemen SVG .Bagi saya, saya dapat dengan mudah mengambil elemen yang dibutuhkan melalui
.childNodes[n]
karena saya tidak memiliki simpul teks yang asing untuk dikhawatirkan. Anda mungkin dapat melakukan hal yang sama, tetapi seperti yang disebutkan di tempat lain di atas, jangan lupa bahwa Anda mungkin mengalami elemen yang tidak terduga.Semoga ini bisa membantu seseorang menggaruk-garuk kepala mencoba mencari tahu mengapa
.children
bekerja di tempat lain di js mereka pada IE modern dan gagal pada dokumen atau elemen SVG.sumber
Hei teman-teman jangan biarkan ruang putih menipu Anda. coba saja ini di browser konsol. gunakan javascript asli. Berikut adalah dan contoh dengan dua set 'ul' dengan kelas yang sama. Anda tidak perlu memiliki daftar 'ul' Anda semua dalam satu baris untuk menghindari ruang putih cukup gunakan jumlah array Anda untuk melompati ruang putih.
Cara mendapatkan ruang di sekitar putih dengan
querySelector()
kemudianchildNodes[]
js Link biola: https://jsfiddle.net/aparadise/56njekdo/sumber
document.querySelector
tidak didukung dengan baik saat itu. b) Pertanyaannya pada dasarnya adalah menanyakan apa perbedaan antarachildren
dan secarachildNodes
internal , mana yang lebih dapat diandalkan, kapan harus memilih satu di antara yang lain. dan c) Karena, seperti ditunjukkan dalam pertanyaan:childNodes
tidak termasuk node spasi putih,children
tidak ...