Saya memiliki fungsi Javascript yang menerima daftar node HTML, tetapi mengharapkan array Javascript (menjalankan beberapa metode Array di atasnya) dan saya ingin memberi makan output Document.getElementsByTagName
yang mengembalikan daftar node DOM.
Awalnya saya berpikir untuk menggunakan sesuatu yang sederhana seperti:
Array.prototype.slice.call(list,0)
Dan itu berfungsi dengan baik di semua browser, kecuali tentu saja Internet Explorer yang mengembalikan kesalahan "objek JScript diharapkan", karena tampaknya daftar simpul DOM yang dikembalikan oleh Document.getElement*
metode bukan objek JScript yang cukup untuk menjadi target pemanggilan fungsi.
Peringatan: Saya tidak keberatan menulis kode khusus Internet Explorer, tetapi saya tidak diizinkan menggunakan pustaka Javascript apa pun seperti JQuery karena saya menulis widget untuk disematkan ke situs web pihak ketiga, dan saya tidak dapat memuat pustaka eksternal yang akan menciptakan konflik untuk klien.
Upaya terakhir saya adalah mengulang daftar simpul DOM dan membuat array sendiri, tetapi adakah cara yang lebih baik untuk melakukannya?
sumber
Jawaban:
NodeLists adalah objek host , menggunakan
Array.prototype.slice
metode pada objek host tidak dijamin akan berfungsi, Spesifikasi ECMAScript menyatakan:Saya akan merekomendasikan Anda untuk membuat fungsi sederhana untuk mengulang
NodeList
dan menambahkan setiap elemen yang ada ke array:MEMPERBARUI:
Seperti yang disarankan jawaban lain, Anda sekarang dapat menggunakan di lingkungan modern sintaks penyebaran atau
Array.from
metode:Tetapi memikirkannya, saya kira kasus penggunaan yang paling umum untuk mengonversi NodeList menjadi Array adalah mengulanginya, dan sekarang
NodeList.prototype
objek tersebut memilikiforEach
metode aslinya , jadi jika Anda berada di lingkungan modern Anda dapat menggunakannya secara langsung, atau memiliki sebuah pollyfill.sumber
array[i] = obj[i]
bukanarray.push(obj[i])
?obj.length
apa ada yang lain selain nilai integer?Di es6 Anda bisa menggunakan sebagai berikut:
Operator penyebar
Menggunakan
Array.from
referensi lebih lanjut di https://developer.mozilla.org/en-US/docs/Web/API/NodeList
sumber
Array.from()
: DArray.from
berfungsi, karena TS mentransformasikannya kenodelist.slice
- yang tidak didukung.Array.from
spread
digunakan.Menggunakan spread (ES2015) , semudah:
[...document.querySelectorAll('p')]
(opsional: gunakan Babel untuk memindahkan kode ES6 di atas ke sintaks ES5)
Cobalah di konsol browser Anda dan lihat keajaibannya:
sumber
Gunakan trik sederhana ini
sumber
Array.prototype.slice
(atau[].slice
seperti yang Anda katakan)? Sebagai catatan, saya ingin berkomentar bahwa kesalahan khusus IE yang saya dokumentasikan di Q terjadi di IE 8 atau lebih rendah, di manamap
tetap tidak diterapkan. Di IE 9 ("mode standar") atau lebih tinggi, keduanyaslice
danmap
berhasil dengan cara yang sama.Meskipun ini bukan tipuan yang tepat, karena tidak ada spesifikasi yang memerlukan pengerjaan elemen DOM, saya telah membuatnya untuk memungkinkan Anda menggunakan
slice()
dengan cara ini: https://gist.github.com/brettz9/6093105PEMBARUAN : Ketika saya mengangkat ini dengan editor spesifikasi DOM4 (menanyakan apakah mereka mungkin menambahkan batasan mereka sendiri ke objek host (sehingga spesifikasi akan mengharuskan pelaksana untuk mengonversi objek ini dengan benar ketika digunakan dengan metode array) di luar spesifikasi ECMAScript yang diperbolehkan untuk implementasi-independensi), dia menjawab bahwa "Objek host kurang lebih sudah usang menurut ES6 / IDL." Saya melihat per http://www.w3.org/TR/WebIDL/#es-array bahwa spesifikasi dapat menggunakan IDL ini untuk mendefinisikan "objek larik platform" tetapi http://www.w3.org/TR/domcore/ tidak Sepertinya tidak menggunakan IDL baru untuk
HTMLCollection
(meskipun sepertinya IDL baru digunakan untukElement.attributes
itu meskipun hanya secara eksplisit menyatakan bahwa ia menggunakan WebIDL untuk DOMString dan DOMTimeStamp). Saya melihat[ArrayClass]
(yang mewarisi dari Array.prototype) digunakan untukNodeList
(danNamedNodeMap
sekarang tidak digunakan lagi untuk mendukung satu-satunya item yang masih akan menggunakannya,Element.attributes
). Bagaimanapun, sepertinya itu akan menjadi standar. ES6Array.from
mungkin juga lebih nyaman untuk konversi seperti itu daripada harus menentukanArray.prototype.slice
dan lebih jelas secara semantik daripada[].slice()
(dan bentuk yang lebih pendek,Array.slice()
("array generik"), sejauh yang saya tahu, tidak menjadi perilaku standar).sumber
Saat ini, di tahun 2018, kita dapat menggunakan ECMAScript 2015 (Edisi ke-6) atau ES6, tetapi tidak semua browser dapat memahaminya (misalnya IE tidak memahami semuanya). Jika mau, Anda bisa menggunakan ES6 sebagai berikut:
var array = [... NodeList];
( sebagai operator penyebaran ) atauvar array = Array.from(NodeList);
.Dalam kasus lain (jika Anda tidak dapat menggunakan ES6), Anda dapat menggunakan cara terpendek untuk mengonversi a
NodeList
menjadiArray
:var array = [].slice.call(NodeList, 0);
.Sebagai contoh:
Tetapi jika Anda ingin mengulang
DOM
daftar node dengan mudah saja, maka Anda tidak perlu mengonversi aNodeList
ke anArray
. Dimungkinkan untuk mengulang item dalamNodeList
menggunakan:Jangan tergoda untuk menggunakan
for...in
ataufor each...in
menghitung item dalam daftar, karena itu juga akan menghitung properti panjang dan item dariNodeList
dan menyebabkan kesalahan jika skrip Anda menganggapnya hanya harus berurusan dengan objek elemen. Juga,for..in
tidak dijamin untuk mengunjungi properti dalam urutan tertentu.for...of
loop akan mengulang objek NodeList dengan benar.Lihat juga:
sumber
Ini harus bekerja, lintas browser dan memberi Anda semua "elemen" node.
sumber