Tidak dapat membaca properti 'addEventListener' dari null


106

Saya harus menggunakan vanilla JavaScript untuk sebuah proyek. Saya punya beberapa fungsi, salah satunya adalah tombol yang membuka menu. Ini berfungsi pada halaman di mana id target ada, tetapi menyebabkan kesalahan pada halaman di mana id tidak ada. Pada halaman di mana fungsi tidak dapat menemukan id, saya menerima kesalahan "Tidak dapat membaca properti 'addEventListener' dari null" dan tidak ada fungsi saya yang lain yang berfungsi.

Di bawah ini adalah kode untuk tombol yang membuka menu.

function swapper() {
toggleClass(document.getElementById('overlay'), 'open');
}

var el = document.getElementById('overlayBtn');
el.addEventListener('click', swapper, false);

var text = document.getElementById('overlayBtn');
text.onclick = function(){
this.innerHTML = (this.innerHTML === "Menu") ? "Close" : "Menu";
return false;
};

Bagaimana saya menangani ini? Saya mungkin perlu membungkus semua kode ini di fungsi lain atau menggunakan pernyataan if / else sehingga hanya mencari id pada halaman tertentu, tetapi tidak yakin persis.


1
dapatkah Anda menunjukkan kode html. tampaknya tidak dapat menemukan elemen dengan id 'overlayBtn'
BlaShadow

2
Pada halaman di mana fungsi tidak dapat menemukan id, saya menerima kesalahan "Tidak dapat membaca properti 'addEventListener' dari null" dan tidak ada fungsi saya yang lain yang berfungsi. Saya pikir jawabannya cukup banyak di pertanyaan itu. Anda tidak dapat menemukan elemen, jadi Anda tidak dapat menambahkan pendengar acara ke sana ...
Etai

1
Ini bisa terjadi begitu saja jika Anda telah menggunakan classhtml Anda dan bukan iddan Anda memanggil getElementByIddalam skrip Anda.
Deke

Jawaban:


198

Saya pikir pendekatan termudah adalah dengan hanya memeriksa bahwa eltidak null sebelum menambahkan pendengar acara:

var el = document.getElementById('overlayBtn');
if(el){
  el.addEventListener('click', swapper, false);
}

mengagumkan. itu berhasil. Saya juga memindahkan fungsi onclick ke pernyataan if itu. Saya memposting kode terakhir di bawah ini.
morocklo

3
itu akan terjadi nullsebelum komponen react dipasang!

Thanks man: D Persis seperti yang saya cari .... Saya punya banyak pendengar di aplikasi saya, dan pendengar tersebar di berbagai tampilan. Jika elemen ada di halaman, itu
merusak

Sangat berguna, terima kasih!
sc_props

113

Tampaknya itu document.getElementById('overlayBtn');kembali nullkarena dijalankan sebelum DOM dimuat sepenuhnya.

Jika Anda meletakkan baris kode ini di bawah

window.onload=function(){
  -- put your code here
}

maka itu akan berjalan tanpa masalah.

Contoh:

window.onload=function(){
    var mb = document.getElementById("b");
    mb.addEventListener("click", handler);
    mb.addEventListener("click", handler2);
}


function handler() {
    $("p").html("<br>" + $("p").text() + "<br>You clicked me-1!<br>");
}

function handler2() {
    $("p").html("<br>" + $("p").text() + "<br>You clicked me-2!<br>");
}

23

Saya menghadapi situasi serupa. Ini mungkin karena skrip dijalankan sebelum halaman dimuat. Dengan menempatkan skrip di bagian bawah halaman, saya menghindari masalah.


1
Ya, menurut saya ada beberapa solusi untuk masalah ini tergantung pada skenarionya.
rpeg

16

Saya mendapatkan kesalahan yang sama, tetapi melakukan pemeriksaan nol sepertinya tidak membantu.

Solusi yang saya temukan adalah membungkus fungsi saya di dalam event listener untuk seluruh dokumen untuk diperiksa ketika DOM selesai memuat.

document.addEventListener('DOMContentLoaded', function () {
    el.addEventListener('click', swapper, false);
});

Saya pikir ini karena saya menggunakan kerangka kerja (Angular) yang mengubah kelas HTML dan ID saya secara dinamis.


1
Saya mengalami masalah yang sama saat bermain dengan Electron. Menyimpannya menggunakan metode yang sama.
Charles

9

Ini hanya karena JS Anda dimuat sebelum bagian HTML dan karenanya tidak dapat menemukan elemen itu. Letakkan saja seluruh kode JS Anda di dalam fungsi yang akan dipanggil saat jendela dimuat.

Anda juga dapat meletakkan kode Javascript Anda di bawah html.


8

skrip dimuat sebelum tubuh, simpan skrip setelah konten


5

Letakkan skrip di akhir tag badan.

<html>
    <body>
        .........
        <script src="main.js"></script>
    </body>
</html>

3

Terima kasih kepada @Rob M. atas bantuannya. Seperti inilah tampilan blok kode terakhir:

function swapper() {
  toggleClass(document.getElementById('overlay'), 'open');
}

var el = document.getElementById('overlayBtn');
if (el){
  el.addEventListener('click', swapper, false);

  var text = document.getElementById('overlayBtn');
  text.onclick = function(){
    this.innerHTML = (this.innerHTML === "Menu") ? "Close" : "Menu";
    return false;
  };
}

2

Saya hanya menambahkan 'async' ke tag skrip saya, yang tampaknya telah memperbaiki masalah tersebut. Saya tidak yakin mengapa, jika seseorang bisa menjelaskan, tetapi itu berhasil untuk saya. Dugaan saya adalah bahwa halaman tersebut tidak menunggu skrip dimuat, sehingga halaman dimuat pada waktu yang sama dengan JavaScript.

Async / Await memungkinkan kita untuk menulis kode asinkron secara sinkron. itu hanya gula sintaksis menggunakan generator dan pernyataan hasil untuk "jeda" eksekusi, memberi kita kemampuan untuk menetapkannya ke variabel!

Berikut link referensi- https://medium.com/siliconwat/how-javascript-async-await-works-3cab4b7d21da


2

Saya mengalami masalah yang sama dan memeriksa null tetapi tidak membantu. Karena skrip dimuat sebelum pemuatan halaman. Jadi hanya dengan menempatkan skrip sebelum tag badan akhir menyelesaikan masalah.


0

Seperti yang dikatakan orang lain, masalahnya adalah skrip dieksekusi sebelum halaman (dan khususnya elemen target) dimuat.

Tapi saya tidak suka solusi penataan ulang konten.

Solusi yang lebih disukai adalah meletakkan pengendali peristiwa di halaman saat memuat peristiwa dan menyetel Pemroses di sana. Itu akan memastikan halaman dan elemen target dimuat sebelum tugas dijalankan. misalnya

    <script>
    function onLoadFunct(){
            // set Listener here, also using suggested test for null
    }
    ....
    </script>

    <body onload="onLoadFunct()" ....>
    .....

0

Saya memiliki kumpulan kutipan bersama dengan nama. Saya menggunakan tombol perbarui untuk memperbarui kutipan terakhir yang terkait dengan nama tertentu tetapi saat mengklik tombol perbarui itu tidak memperbarui. Saya menyertakan kode di bawah ini untuk file server.js dan file js eksternal (main.js).

main.js (js eksternal)

var update = document.getElementById('update');
if (update){
update.addEventListener('click', function () {

  fetch('quotes', {
  method: 'put',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({
    'name': 'Muskan',
    'quote': 'I find your lack of faith disturbing.'
  })
})var update = document.getElementById('update');
if (update){
update.addEventListener('click', function () {

  fetch('quotes', {
  method: 'put',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({
    'name': 'Muskan',
    'quote': 'I find your lack of faith disturbing.'
  })
})
.then(res =>{
    if(res.ok) return res.json()
})
.then(data =>{
    console.log(data);
    window.location.reload(true);
})
})
}

file server.js

app.put('/quotes', (req, res) => {
  db.collection('quotations').findOneAndUpdate({name: 'Vikas'},{
    $set:{
        name: req.body.name,
        quote: req.body.quote
    }
  },{
    sort: {_id: -1},
    upsert: true
  },(err, result) =>{
    if (err) return res.send(err);
    res.send(result);
  })

})

0

Terima kasih dari semua, Muat Skrip di halaman tertentu yang Anda gunakan, bukan untuk semua halaman, terkadang menggunakan swiper.js atau pustaka lain dapat menyebabkan pesan kesalahan ini, satu-satunya cara untuk menyelesaikan masalah ini adalah memuat pustaka JS pada halaman tertentu ID tersebut ada dan mencegah pemuatan perpustakaan yang sama di semua halaman.

Semoga ini membantu Anda.


0

Saya memiliki masalah yang sama, tetapi ID saya ada. Jadi saya mencoba menambahkan "window.onload = init;" Lalu saya membungkus kode JS asli saya dengan fungsi init (sebut saja apa yang Anda inginkan). Ini berfungsi, jadi setidaknya dalam kasus saya, saya menambahkan pendengar acara sebelum dokumen saya dimuat. Ini bisa jadi apa yang Anda alami juga.


-1

Ini karena elemen belum dimuat pada saat bundle js dijalankan.

Saya akan memindahkan <script src="sample.js" type="text/javascript"></script>ke bagian paling bawah index.htmlfile. Dengan cara ini Anda dapat memastikan skrip dijalankan setelah semua elemen html telah diurai dan dirender.


Salah. Ini pemikiran jadul. Memuat di akhir akan menunda pemuatan, seperti yang Anda nyatakan, tetapi itu tidak memastikan DOM ditarik sepenuhnya . Saya memiliki halaman lama yang menggunakan peretasan ini gagal dijalankan karena penarikan DOM lebih lambat daripada pemuatan. Jawaban ini memastikan DOM diambil sebelum eksekusi.
Machavity

-3

Tambahkan semua event listener saat jendela dimuat.Bekerja seperti pesona di mana pun Anda meletakkan tag skrip.

window.addEventListener("load", startup);

function startup() {

  document.getElementById("el").addEventListener("click", myFunc);
  document.getElementById("el2").addEventListener("input", myFunc);

}

myFunc(){}

Penggambaran halaman terkadang membutuhkan waktu lebih lama daripada waktu pemuatan skrip, jadi posisinya tidak terlalu penting dalam semua kasus. Menambahkan pendengar adalah cara yang lebih disukai, tetapi loadjuga tidak digunakan lagi karena alasan yang sama. DOMContentLoaded adalah cara yang lebih disukai, karena ini hanya diaktifkan setelah DOM ditarik sepenuhnya.
Machavity

Terima kasih saya akan mencoba. Saya mendapat jawaban saya dari jaringan Mozilla. Saya pikir itu adalah sumber yang dapat dipercaya.
Natalie Jimenez
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.