Saya ingin tahu apakah perbezaan antara querySelectorAll
dan getElementsByClassName
B> kod>
Dari pautan ini, saya mengetahui bahawa menggunakan querySelector
, saya boleh menulis document.querySelector(".myclass")
;code>myclass, dan document.querySelector("#myid")
untuk mendapatkan elemen dengan ID myid
. Tetapi saya sudah boleh mencapai fungsi ini menggunakan getElementsByClassName
dan getElementById
. Mana satu yang patut diutamakan?
Selain itu, saya sedang bekerja dalam XPages dan ID dijana secara dinamik, mengandungi titik bertindih dan kelihatan seperti ini view:_id1:inputText1
. Jadi apabila saya menulis document.querySelector("#view:_id1:inputText1")
, ia tidak berfungsi. Tetapi apabila saya menulis document.getElementById("view:_id1:inputText1")
, ia berfungsi. Sebarang idea mengapa ini berlaku?
Untuk jawapan ini, saya akan menghubungi
querySelector
和querySelectorAll
称为querySelector*,将getElementById
、getElementsByClassName
、getElementsByTagName
和getElementsByName
getElement*.Kebanyakan maklumat ini boleh disahkan dalam spesifikasi, dan kebanyakannya diperoleh daripada pelbagai penanda aras yang saya jalankan semasa menulis. Spesifikasi:https://dom.spec.whatwg.org/
Perbezaan utama
querySelector
和getElementById
都返回单个元素。querySelectorAll
和getElementsByName
都返回NodeList。getElementsByClassName
和getElementsByTagName
Kedua-duanya mengembalikan HTMLCollection. Kedua-dua NodeList dan HTMLCollection dipanggil koleksi elemen.Konsep ini diringkaskan dalam jadual di bawah.
Butiran, petua dan contoh
HTMLCollection tidak seperti tatasusunan seperti NodeList dan tidak menyokong .forEach(). Saya mendapati pengendali penyebaran berguna untuk mengatasi masalah ini:
[...document.getElementsByClassName("someClass")].forEach()
dilaksanakan pada setiap elemen dan secara global
document
都可以访问所有这些函数,除了getElementById
和getElementsByName
,它们只在document
.Merantai panggilan getElement* dan bukannya querySelector* akan meningkatkan prestasi, terutamanya pada DOM yang sangat besar. Biasanya lebih pantas walaupun pada DOM kecil dan/atau rantai yang sangat panjang. Walau bagaimanapun, kebolehbacaan querySelector* harus diutamakan berbanding kebolehbacaan melainkan anda tahu anda memerlukan prestasi.
querySelectorAll
Biasanya lebih sukar untuk ditindih kerana anda perlu memilih elemen daripada NodeList atau HTMLCollection pada setiap langkah. Contohnya, kod berikuttidak berfungsi:document.getElementsByClassName("someClass").getElementsByTagName("div")
Oleh kerana anda hanya boleh menggunakan getElements* pada satu elemen, bukan koleksi, tetapi jika anda hanya mahukan satu elemen maka:
document.querySelector("#someId .someClass div")
boleh ditulis sebagai:
document.getElementById("someId").getElementsByClassName("someClass")[0].getElementsByTagName("div")[0]
Perhatikan penggunaan
[0]
,以获取集合的第一个元素,最终结果只有一个元素,就像使用querySelector
yang sama dalam setiap langkah pemulangan koleksi.Memandangkan semua elemen boleh dipanggil menggunakan querySelector* dan getElement*, operasi rantaian mungkin menggunakan kedua-dua panggilan, yang sangat berguna apabila anda mahukan beberapa keuntungan prestasi tetapi tidak boleh mengelak daripada menggunakan querySelector yang tidak boleh ditulis dengan getElement* memanggilnya berfungsi.
Walaupun biasanya mudah untuk mengetahui sama ada pemilih boleh ditulis menggunakan hanya getElement* panggilan, terdapat satu kes yang mungkin tidak jelas:
document.querySelectorAll(".class1.class2")
boleh ditulis semula sebagai
document.getElementsByClassName("class1 class2")
Menggunakan getElement* pada elemen statik yang diperolehi dengan querySelector* akan menyebabkan elemen menjadi dinamik berbanding subset DOM statik yang disalin oleh querySelector, tetapi statik berbanding DOM dokumen penuh... itulah unsur dinamik/statik yang mudah Inilah di mana penjelasan mula bercelaru. Anda harus cuba mengelakkan situasi di mana anda perlu bimbang tentang perkara ini, tetapi jika ia wujud, ingat bahawa panggilan querySelector* menyalin elemen yang mereka temui sebelum mengembalikan rujukan, manakala panggilan getElement* mendapatkan rujukan terus tanpa menyalin.
querySelector* dan
getElementById
以前序、深度优先的方式遍历元素,在规范中称为“树顺序”。对于其他getElement*调用,从规范中我无法确定它们是否与树顺序相同,但getElementsByClassName(".someClass")[0]
可能在每个浏览器中结果不可靠。getElementById("#someId")
harus boleh dipercayai walaupun anda mempunyai beberapa salinan id yang sama pada halaman anda.Saya terpaksa meneliti isu ini semasa saya bekerja pada halaman tatal yang tidak terhingga dan saya fikir ini mungkin situasi biasa di mana prestasi menjadi isu. Kami mempunyai acara onScroll dalam kod kami yang mengandungi panggilan querySelectorAll. Walaupun panggilan adalah terhad pada kadar, halaman itu akan ranap jika anda menatal cukup jauh, pada ketika itu akan terdapat terlalu banyak panggilan yang berulang atas terlalu banyak elemen untuk disemak oleh penyemak imbas. Saiz DOM adalah berkaitan dalam kes penggunaan ini, jadi dalam kod yang dijalankan pada halaman tatal tak terhingga, panggilan getElement* lebih diutamakan.
Sintaks dan sokongan penyemak imbas.
querySelector
Lebih berguna apabila anda ingin menggunakan pemilih yang lebih kompleks.Sebagai contoh, senarai semua elemen kepunyaan kelas foo:
Aksara.foo li
:
mempunyai makna istimewa dalam pemilih. Anda perlu melarikan diri. (Watak pemilih melarikan diri juga mempunyai makna istimewa dalam rentetan JS, jadi anda perlu melarikan diriitjuga).