Apa alasan yang memungkinkan document.getElementById
, $("#id")
atau metode DOM / pemilih jQuery lainnya yang tidak menemukan elemen?
Contoh masalah termasuk:
- jQuery diam-diam gagal mengikat event handler
- jQuery "pengambil" metode (
.val()
,.html()
,.text()
) kembaliundefined
- Metode DOM standar yang
null
menghasilkan beberapa kesalahan:
Uncaught TypeError: Tidak dapat mengatur properti '...' dari null Uncaught TypeError: Tidak dapat membaca properti '...' dari nol
Bentuk yang paling umum adalah:
UnEught TypeError: Tidak dapat mengatur properti 'onclick' dari nol
UnEught TypeError: Tidak dapat membaca properti 'addEventListener' dari nol
UnEught TypeError: Tidak dapat membaca properti 'style' dari nol
javascript
jquery
dom
Felix Kling
sumber
sumber
Jawaban:
Elemen yang Anda coba temukan tidak ada di DOM saat skrip Anda berjalan.
Posisi skrip yang bergantung pada DOM Anda dapat memiliki efek mendalam pada perilakunya. Browser mem-parsing dokumen HTML dari atas ke bawah. Elemen ditambahkan ke DOM dan skrip (umumnya) dieksekusi saat ditemui. Ini berarti ketertiban penting. Biasanya, skrip tidak dapat menemukan elemen yang muncul kemudian di markup karena elemen-elemen tersebut belum ditambahkan ke DOM.
Pertimbangkan markup berikut; skrip # 1 gagal menemukan
<div>
sedangkan skrip # 2 berhasil:Jadi, apa yang harus kamu lakukan? Anda punya beberapa opsi:
Opsi 1: Pindahkan skrip Anda
Pindahkan skrip Anda lebih jauh ke bawah halaman, tepat sebelum tag penutup tubuh. Diatur dengan cara ini, sisa dokumen diuraikan sebelum skrip Anda dijalankan:
Catatan: Menempatkan skrip di bagian bawah umumnya dianggap praktik terbaik .
Opsi 2: jQuery's
ready()
Tunda skrip Anda hingga DOM selesai diuraikan, menggunakan :
$(handler)
Catatan: Anda bisa saja mengikat
DOMContentLoaded
atau tetapi masing-masing memiliki peringatan. jQuery's memberikan solusi hybrid.window.onload
ready()
Opsi 3: Delegasi Acara
Ketika sebuah elemen memunculkan sebuah event (asalkan itu adalah event yang menggelegak dan tidak ada yang menghentikan penyebarannya), masing-masing orangtua dalam leluhur elemen tersebut menerima event tersebut juga. Itu memungkinkan kita untuk melampirkan pawang ke elemen yang ada dan contoh peristiwa saat mereka muncul dari keturunannya ... bahkan yang ditambahkan setelah pawang dilampirkan. Yang harus kita lakukan adalah memeriksa acara untuk melihat apakah itu dibangkitkan oleh elemen yang diinginkan dan, jika demikian, jalankan kode kita.
jQuery
on()
melakukan logika itu untuk kita. Kami hanya menyediakan nama acara, pemilih untuk keturunan yang diinginkan, dan pengendali acara:Catatan: Biasanya, pola ini dicadangkan untuk elemen yang tidak ada pada waktu buka atau untuk menghindari melampirkan sejumlah besar penangan. Penting juga menunjukkan bahwa sementara saya telah melampirkan pawang ke
document
(untuk tujuan demonstratif), Anda harus memilih leluhur tepercaya terdekat.Opsi 4:
defer
AtributGunakan
defer
atribut<script>
.Untuk referensi, inilah kode dari skrip eksternal itu :
Catatan:
defer
Atribut tentu saja tampak seperti peluru ajaib tetapi penting untuk menyadari peringatan ...1.
defer
hanya dapat digunakan untuk skrip eksternal, yaitu: mereka yang memilikisrc
atribut.2. Waspadai dukungan browser , yaitu: implementasi buggy di IE <10
sumber
<head>
dan menggunakandefer
skrip (saya tidak harus mendukung browser yang tidak kompatibel lama-buruk)defer
danasync
memiliki dukungan yang cukup luas - bahkan mencapai beberapa versi peramban yang jauh lebih tua. Mereka memiliki keuntungan tambahan dengan jelas, secara eksplisit menandakan perilaku yang dimaksud. Ingat saja bahwa atribut ini hanya berfungsi untuk skrip yang menetapkansrc
atribut, yaitu: skrip eksternal. Timbang manfaatnya. Mungkin menggunakan keduanya? Panggilanmu.Singkat dan sederhana: Karena elemen yang Anda cari belum ada dalam dokumen (belum).
Untuk sisa jawaban ini saya akan menggunakan
getElementById
sebagai contoh, tetapi hal yang sama berlaku untukgetElementsByTagName
,querySelector
dan metode DOM lainnya yang memilih elemen.Kemungkinan Alasan
Ada dua alasan mengapa suatu elemen mungkin tidak ada:
Elemen dengan ID yang diteruskan benar-benar tidak ada dalam dokumen. Anda harus mengecek apakah ID yang Anda berikan
getElementById
benar - benar cocok dengan ID dari elemen yang ada di HTML (yang dihasilkan) dan Anda belum salah mengeja ID (ID peka huruf besar kecil !).Secara kebetulan, di sebagian besar browser kontemporer , yang menerapkan
querySelector()
danquerySelectorAll()
metode, notasi gaya-CSS digunakan untuk mengambil elemen denganid
, misalnyadocument.querySelector('#elementID')
:, sebagai lawan dari metode dimana elemen diambil oleh diid
bawahnyadocument.getElementById('elementID')
; pada karakter pertama#
sangat penting, pada karakter kedua akan menyebabkan elemen tidak diambil.Elemen tidak ada pada saat Anda menelepon
getElementById
.Kasus terakhir cukup umum. Browser mem-parsing dan memproses HTML dari atas ke bawah. Itu berarti bahwa setiap panggilan ke elemen DOM yang terjadi sebelum elemen DOM muncul di HTML, akan gagal.
Perhatikan contoh berikut:
The
div
muncul setelah parascript
. Pada saat script dijalankan, elemen tidak ada belum dangetElementById
akan kembalinull
.jQuery
Hal yang sama berlaku untuk semua penyeleksi dengan jQuery. jQuery tidak akan menemukan elemen jika Anda salah mengeja pemilih atau Anda mencoba memilihnya sebelum benar-benar ada .
Sentuhan tambahan adalah ketika jQuery tidak ditemukan karena Anda telah memuat skrip tanpa protokol dan berjalan dari sistem file:
sintaks ini digunakan untuk memungkinkan skrip memuat melalui HTTPS pada halaman dengan protokol https: // dan untuk memuat versi HTTP pada halaman dengan protokol http: //
Ini memiliki efek samping yang disayangkan ketika mencoba dan gagal memuat
file://somecdn.somewhere.com...
Solusi
Sebelum Anda melakukan panggilan ke
getElementById
(atau metode DOM apa pun), pastikan elemen yang ingin Anda akses ada, yaitu DOM dimuat.Ini dapat dipastikan dengan hanya menempatkan JavaScript Anda setelah elemen DOM yang sesuai
dalam hal ini Anda juga dapat meletakkan kode tepat sebelum tag penutup tubuh (
</body>
) (semua elemen DOM akan tersedia pada saat skrip dijalankan).Solusi lain termasuk mendengarkan acara
load
[MDN] atauDOMContentLoaded
[MDN] . Dalam kasus ini, tidak masalah di mana dalam dokumen Anda menempatkan kode JavaScript, Anda hanya harus ingat untuk meletakkan semua kode pemrosesan DOM dalam event handler.Contoh:
Silakan lihat artikel di quirksmode.org untuk informasi lebih lanjut mengenai penanganan acara dan perbedaan browser.
jQuery
Pertama, pastikan jQuery dimuat dengan benar. Gunakan alat pengembang browser untuk mencari tahu apakah file jQuery ditemukan dan perbaiki URL jika tidak (mis. Tambahkan skema
http:
atauhttps:
di awal, sesuaikan jalur, dll.)Mendengarkan
load
/DOMContentLoaded
events adalah persis apa yang dilakukan jQuery dengan.ready()
[docs] . Semua kode jQuery Anda yang memengaruhi elemen DOM harus ada di dalam pengendali event tersebut.Bahkan, tutorial jQuery secara eksplisit menyatakan:
Atau Anda juga dapat menggunakan sintaks steno:
Keduanya setara.
sumber
ready
acara untuk mencerminkan sintaks yang disukai "baru", atau lebih baik membiarkannya apa adanya sehingga berfungsi di versi yang lebih lama?$(window).load()
(dan alternatif mungkin sintaksis dengan$(document).ready()
,$(function(){})
itu tampaknya terkait, tapi? Terasa sedikit tangensial ke titik Anda membuat Anda..load
. Mengenai alternatif sintaks, mereka dapat dicari dalam dokumentasi tetapi karena jawaban harus lengkap, mungkin sebenarnya layak untuk ditambahkan. Kemudian lagi, saya cukup yakin ini sedikit spesifik tentang jQuery sudah dijawab dan mungkin tercakup dalam jawaban lain dan menghubungkannya mungkin sudah cukup..load
sudah usang: api.jquery.com/load-event . Saya tidak tahu apakah ini untuk gambar saja atauwindow
juga.Alasan mengapa pemilih berbasis id tidak berfungsi
Solusi
Coba akses elemen setelah deklarasi atau gunakan hal-hal seperti
$(document).ready();
Untuk elemen yang berasal dari respons Ajax, gunakan
.bind()
metode jQuery. Versi jQuery yang lebih lama memiliki.live()
hal yang sama.Gunakan alat [misalnya, plugin pengembang web untuk browser] untuk menemukan id duplikat dan menghapusnya.
sumber
Seperti yang ditunjukkan oleh @FelixKling, skenario yang paling mungkin adalah bahwa node yang Anda cari belum ada (belum).
Namun, praktik pembangunan modern sering dapat memanipulasi elemen dokumen di luar pohon dokumen baik dengan DocumentFragments atau hanya melepaskan / memasang kembali elemen saat ini secara langsung. Teknik-teknik semacam itu dapat digunakan sebagai bagian dari templating JavaScript atau untuk menghindari operasi pengecatan ulang yang berlebihan sementara elemen-elemen yang dipertanyakan sedang banyak diubah.
Demikian pula, fungsionalitas "Shadow DOM" baru yang digulirkan di browser modern memungkinkan elemen menjadi bagian dari dokumen, tetapi tidak dapat ditanyakan oleh document.getElementById dan semua metode saudaranya (querySelector, dll.). Ini dilakukan untuk merangkum fungsionalitas dan secara khusus menyembunyikannya.
Namun, sekali lagi, kemungkinan besar unsur yang Anda cari sebenarnya belum ada di dokumen, dan Anda harus melakukan seperti yang disarankan Felix. Namun, Anda juga harus menyadari bahwa itu bukan satu-satunya alasan bahwa suatu elemen mungkin tidak dapat dihindarkan (baik sementara atau permanen).
sumber
Jika elemen yang Anda coba akses berada di dalam
iframe
dan Anda mencoba mengaksesnya di luar konteksiframe
ini juga akan menyebabkannya gagal.Jika Anda ingin mendapatkan elemen dalam iframe, Anda bisa mengetahui caranya di sini .
sumber
Jika urutan eksekusi skrip bukan masalah, kemungkinan penyebab lain masalahnya adalah bahwa elemen tidak dipilih dengan benar:
getElementById
membutuhkan string yang lewat menjadi ID kata demi kata , dan bukan yang lain. Jika Anda#
awali string yang diteruskan dengan , dan ID tidak dimulai dengan#
, tidak ada yang akan dipilih:Demikian pula, untuk
getElementsByClassName
, jangan awali string yang diteruskan dengan.
:Dengan kueriSelektor, kueriSelektorAll, dan jQuery, untuk mencocokkan elemen dengan nama kelas tertentu, letakkan
.
langsung di depan kelas. Demikian pula, untuk mencocokkan elemen dengan ID tertentu, letakkan#
langsung di depan ID:Aturan di sini, dalam banyak kasus, identik dengan yang untuk penyeleksi CSS, dan dapat dilihat secara rinci di sini .
Untuk mencocokkan elemen yang memiliki dua atribut atau lebih (seperti dua nama kelas, atau nama kelas dan
data-
atribut), letakkan pemilih untuk setiap atribut di sebelah satu sama lain dalam string pemilih, tanpa spasi yang memisahkannya (karena spasi menunjukkan yang keturunan pemilih ). Misalnya, untuk memilih:gunakan string kueri
.foo.bar
. Memilihgunakan string kueri
.foo[data-bar="someData"]
. Untuk memilih di<span>
bawah ini:gunakan
div.parent > span[data-username="bob"]
.Kapitalisasi dan ejaan memang penting untuk semua hal di atas. Jika kapitalisasi berbeda, atau ejaannya berbeda, elemen tidak akan dipilih:
Anda juga perlu memastikan metode memiliki huruf besar dan huruf yang benar. Gunakan salah satu dari:
Ejaan atau huruf besar apa pun lainnya tidak akan berfungsi. Misalnya,
document.getElementByClassName
akan melempar kesalahan.Pastikan Anda meneruskan string ke metode pemilih ini. Jika Anda melewatkan sesuatu yang tidak string untuk
querySelector
,getElementById
, dll, itu hampir pasti tidak akan bekerja.sumber
Ketika saya mencoba kode Anda, itu berhasil.
Satu-satunya alasan bahwa acara Anda tidak berfungsi, mungkin karena DOM Anda belum siap dan tombol Anda dengan id "event-btn" belum siap. Dan javascript Anda dieksekusi dan mencoba untuk mengikat acara dengan elemen itu.
Sebelum menggunakan elemen DOM untuk mengikat, elemen itu harus siap. Ada banyak opsi untuk melakukan itu.
Option1: Anda dapat memindahkan kode penjilidan acara Anda dalam acara siap dokumen. Suka:
Option2: Anda dapat menggunakan acara batas waktu, sehingga pengikatan tertunda selama beberapa detik. Suka:
Option3: pindahkan javascript Anda ke bagian bawah halaman Anda.
Saya harap ini membantu Anda.
sumber
masalahnya adalah elemen dom 'speclist' tidak dibuat pada saat kode javascript dieksekusi. Jadi saya memasukkan kode javascript ke dalam sebuah fungsi dan memanggil fungsi itu pada event onload tubuh.
sumber
Solusi saya adalah untuk tidak menggunakan id dari elemen anchor:
<a id='star_wars'>Place to jump to</a>
. Rupanya pisau cukur dan kerangka spa lainnya memiliki masalah melompat ke jangkar di halaman yang sama. Untuk menyiasati itu saya harus menggunakandocument.getElementById('star_wars')
. Namun hal ini tidak bekerja sampai aku meletakkan id dalam elemen paragraf sebagai gantinya:<p id='star_wars'>Some paragraph<p>
.Contoh menggunakan bootstrap:
sumber