Rumah  >  Soal Jawab  >  teks badan

Dalam JavaScript, perbezaan antara querySelector dan querySelectorAll dan getElementsByClassName dan getElementById

<p>Saya ingin tahu apakah perbezaan antara <kod>querySelector</code> dan <code>querySelectorAll</code> dan <code>getElementsByClassName</code>B> kod> </p> <p>Dari pautan ini, saya mengetahui bahawa menggunakan <code>querySelector</code>, saya boleh menulis <code>document.querySelector(".myclass")</code> ;code>myclass</code>, dan <code>document.querySelector("#myid")</code> untuk mendapatkan elemen dengan ID <code>myid</code>. Tetapi saya sudah boleh mencapai fungsi ini menggunakan <code>getElementsByClassName</code> dan <code>getElementById</code>. Mana satu yang patut diutamakan? </p> <p>Selain itu, saya sedang bekerja dalam XPages dan ID dijana secara dinamik, mengandungi titik bertindih dan kelihatan seperti ini <code>view:_id1:inputText1</code>. Jadi apabila saya menulis <code>document.querySelector("#view:_id1:inputText1")</code>, ia tidak berfungsi. Tetapi apabila saya menulis <code>document.getElementById("view:_id1:inputText1")</code>, ia berfungsi. Sebarang idea mengapa ini berlaku? </p>
P粉442576165P粉442576165447 hari yang lalu636

membalas semua(2)saya akan balas

  • P粉008829791

    P粉0088297912023-08-22 20:21:16

    Untuk jawapan ini, saya akan menghubungi querySelectorquerySelectorAll称为querySelector*,将getElementByIdgetElementsByClassNamegetElementsByTagNamegetElementsByNamegetElement*.

    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

    1. querySelector* lebih fleksibel kerana anda boleh melepasi mana-mana pemilih CSS3, bukan sekadar id, teg atau kelas yang mudah.
    2. Prestasi querySelector* berbeza mengikut saiz DOM yang dipanggil. Lebih tepatnya, panggilan querySelector* dijalankan dalam masa O(n), manakala panggilan getElement* dijalankan dalam masa O(1), dengan n ialah jumlah bilangan semua elemen anak bagi elemen atau dokumen yang membuat panggilan itu.
    3. Jenis pemulangan panggilan ini berbeza. querySelectorgetElementById都返回单个元素。querySelectorAllgetElementsByName都返回NodeList。getElementsByClassNamegetElementsByTagNameKedua-duanya mengembalikan HTMLCollection. Kedua-dua NodeList dan HTMLCollection dipanggil koleksi elemen.
    4. Koleksi boleh mengembalikan koleksi "live" atau "statik" masing-masing. Ini tidak ditunjukkan dalam jenis sebenar yang mereka kembalikan. Panggilan getElements* mengembalikan koleksi langsung, manakala querySelectorAll mengembalikan koleksi statik. Dari pemahaman saya, koleksi langsung mengandungi rujukan kepada elemen dalam DOM, manakala koleksi statik mengandungi salinan elemen. Anda juga boleh menyemak ulasan @Jan Feldmann di bawah untuk perspektif yang berbeza. Saya tidak menemui cara yang baik untuk memasukkan ini ke dalam jawapan saya, tetapi ini mungkin pemahaman yang lebih tepat.

    Konsep ini diringkaskan dalam jadual di bawah.

    Function               | Live? | Type           | Time Complexity
    querySelector          |       | Element        |  O(n)
    querySelectorAll       |   N   | NodeList       |  O(n)
    getElementById         |       | Element        |  O(1)
    getElementsByClassName |   Y   | HTMLCollection |  O(1)
    getElementsByTagName   |   Y   | HTMLCollection |  O(1)
    getElementsByName      |   Y   | NodeList       |  O(1)
    

    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都可以访问所有这些函数,除了getElementByIdgetElementsByName,它们只在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. querySelectorAllBiasanya lebih sukar untuk ditindih kerana anda perlu memilih elemen daripada NodeList atau HTMLCollection pada setiap langkah. Contohnya, kod berikut tidak 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.

    balas
    0
  • P粉238355860

    P粉2383558602023-08-22 16:58:04

    Sintaks dan sokongan penyemak imbas.

    querySelectorLebih berguna apabila anda ingin menggunakan pemilih yang lebih kompleks.

    Sebagai contoh, senarai semua elemen kepunyaan kelas foo: .foo li

    Aksara

    : mempunyai makna istimewa dalam pemilih. Anda perlu melarikan diri. (Watak pemilih melarikan diri juga mempunyai makna istimewa dalam rentetan JS, jadi anda perlu melarikan diri it juga).

    document.querySelector("#view\:_id1\:inputText1")

    balas
    0
  • Batalbalas