Saya sedang mengerjakan skrip pendek untuk mengubah <abbr>
teks bagian dalam elemen, tetapi ternyata nodelist
tidak memiliki forEach
metode. Aku tahu itu nodelist
tidak mewarisi Array
, tapi bukankah itu forEach
metode yang berguna untuk dimiliki? Apakah ada masalah implementasi tertentu saya tidak sadar bahwa mencegah menambahkan forEach
ke nodelist
?
Catatan: Saya tahu bahwa Dojo dan jQuery memiliki forEach
beberapa bentuk untuk nodelist mereka. Saya tidak dapat menggunakan keduanya karena keterbatasan.
javascript
arrays
dom
foreach
Ular dan Kopi
sumber
sumber
Jawaban:
NodeList sekarang memiliki forEach () di semua browser utama
Lihat nodeList forEach () di MDN .
Jawaban asli
Tak satu pun dari jawaban ini menjelaskan mengapa NodeList tidak mewarisi dari Array, sehingga memungkinkan NodeList untuk memiliki
forEach
dan yang lainnya.Jawabannya ada di utas diskusi es ini . Singkatnya, ini merusak web:
Artinya, beberapa kode melakukan sesuatu seperti
if (x instanceof Array) { otherArray.concat(x); } else { doSomethingElseWith(x); }
Namun,
concat
akan memperlakukan larik "nyata" (bukan turunan dari Array) secara berbeda dari objek lain:[1, 2, 3].concat([4, 5, 6]) // [1, 2, 3, 4, 5, 6] [1, 2, 3].concat(4) // [1, 2, 3, 4]
jadi itu berarti bahwa kode di atas rusak ketika
x
menjadi NodeList, karena sebelum itu turun kedoSomethingElseWith(x)
jalur, sedangkan setelah itu turun keotherArray.concat(x)
jalur, yang melakukan sesuatu yang aneh karenax
bukan array nyata.Untuk beberapa waktu ada proposal untuk
Elements
kelas yang merupakan subkelas Array yang sebenarnya, dan akan digunakan sebagai "NodeList baru". Namun, itu telah dihapus dari Standar DOM , setidaknya untuk saat ini, karena belum dapat diterapkan karena berbagai alasan teknis dan spesifikasi.sumber
NodeList now has forEach() in all major browsers
sepertinya menyiratkan bahwa IE bukanlah browser utama. Mudah-mudahan itu benar bagi sebagian orang, tapi itu tidak benar bagi saya (belum).Anda dapat melakukan
Array.prototype.forEach.call (nodeList, function (node) { // Your code here. } );
sumber
Array.prototype.forEach.call
dapat disingkat menjadi[].forEach.call
Array.prototype.forEach.call
, itu membuat array kosong dan menggunakanforEach
metodenya.Anda dapat mempertimbangkan untuk membuat array node baru.
var nodeList = document.getElementsByTagName('div'), nodes = Array.prototype.slice.call(nodeList,0); // nodes is an array now. nodes.forEach(function(node){ // do your stuff here. });
Catatan: Ini hanyalah daftar / larik referensi node yang kami buat di sini, tidak ada node duplikat.
nodes[0] === nodeList[0] // will be true
sumber
Array.prototype.forEach.call(nodeList, fun)
.var forEach = Array.prototype.forEach.call(nodeList, callback);
. Sekarang Anda cukup meneleponforEach(nodeList, callback);
Jangan pernah katakan tidak, ini tahun 2016 dan
NodeList
objek telah menerapkanforEach
metode di chrome terbaru (v52.0.2743.116).Masih terlalu dini untuk menggunakannya dalam produksi karena browser lain belum mendukung ini (diuji FF 49) tetapi saya kira ini akan segera distandarisasi.
sumber
Array.prototype.slice.call(nodelist).forEach(…)
adalah melakukan yang standar dan berfungsi di browser lama.Singkatnya, itu adalah konflik desain untuk mengimplementasikan metode itu.
Dari MDN:
Sumber: https://developer.mozilla.org/en-US/docs/DOM/NodeList (gulir ke bawah ke Why can't I use forEach atau map on a NodeList? )
sumber
myNodeList --> NodeList.prototype --> Array.prototype --> Object.prototype --> null
?Jika Anda ingin menggunakan forEach di NodeList, cukup salin fungsi itu dari Array:
NodeList.prototype.forEach = Array.prototype.forEach;
Itu saja, sekarang Anda dapat menggunakannya dengan cara yang sama seperti yang Anda lakukan untuk Array:
document.querySelectorAll('td').forEach(function(o){ o.innerHTML = 'text'; });
sumber
Di ES2015, Anda sekarang dapat menggunakan
forEach
metode ke nodeList.document.querySelectorAll('abbr').forEach( el => console.log(el));
Lihat Tautan MDN
Namun jika Anda ingin menggunakan Koleksi HTML atau objek lain yang mirip array, di es2015, Anda dapat menggunakan
Array.from()
metode. Metode ini mengambil objek seperti array atau iterable (termasuk nodeList, Koleksi HTML, string, dll.) Dan mengembalikan instance Array baru. Anda bisa menggunakannya seperti ini:const elements = document.getElementsByTagName('abbr'); Array.from(elements).forEach( el => console.log(el));
Karena
Array.from()
metode ini dapat diubah, Anda dapat menggunakannya dalam kode es5 seperti inivar elements = document.getElementsByTagName('abbr'); Array.from(elements).forEach( function(el) { console.log(el); });
Untuk detailnya, lihat halaman MDN .
Untuk memeriksa dukungan browser saat ini .
ATAU
cara es2015 lainnya adalah dengan menggunakan operator penyebaran.
[...document.querySelectorAll('abbr')].forEach( el => console.log(el));
Operator penyebaran MDN
Spread Operator - Dukungan Browser
sumber
Solusi saya:
//foreach for nodeList NodeList.prototype.forEach = Array.prototype.forEach; //foreach for HTML collection(getElementsByClassName etc.) HTMLCollection.prototype.forEach = Array.prototype.forEach;
sumber
NodeList adalah bagian dari DOM API. Lihat binding ECMAScript yang juga berlaku untuk JavaScript. http://www.w3.org/TR/DOM-Level-2-Core/ecma-script-binding.html . NodeList dan properti panjang baca-saja dan item (indeks) berfungsi untuk mengembalikan sebuah node.
Jawabannya adalah, Anda harus mengulang. Tidak ada alternatif lain. Foreach tidak akan berhasil. Saya bekerja dengan binding Java DOM API dan memiliki masalah yang sama.
sumber
NodeList.forEach(function(item, index, nodeList) { // code block here });
Di IE, gunakan jawaban akuhn :
[].forEach.call(NodeList, function(item, index, array) { // code block here });
sumber