Question

[Solved] Cannot read property ‘addEventListener’ of null

I have to use vanilla JavaScript for a project. I have a few functions, one of which is a button that opens a menu. It works on pages where the target id exists, but causes an error on pages where the id doesn’t exist. On those pages where the function cannot find the id, I receive a “Cannot read property ‘addEventListener’ of null ” error and none of my other functions work.

Below is the code for the button that opens the 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;
};

How do I deal with this? I probably need to all wrap this code in another function or use an if/else statement so that it only searches for the id on specific pages, but not sure exactly.

Enquirer: morocklo

||

Solution #1:

I think the easiest approach would be to just check that el is not null before adding an event listener:

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

Solution #2:

It seems that document.getElementById('overlayBtn'); is returning null because it executes before the DOM fully loads.

If you put this line of code under

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

then it will run without issue.

Example:

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>");
}
Respondent: Dilip Agheda

Solution #3:

I faced a similar situation. This is probably because the script is executed before the page loads. By placing the script at the bottom of the page, I circumvented the problem.

Respondent: sridhar

Solution #4:

I was getting the same error, but performing a null check did not seem to help.

The solution I found was to wrap my function inside an event listener for the whole document to check when the DOM finished loading.

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

I think this is because I am using a framework (Angular) that is changing my HTML classes and ID’s dynamically.

Respondent: MattSidor

Solution #5:

Put script at the end of body tag.

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

Solution #6:

It’s just bcz your JS gets loaded before the HTML part and so it can’t find that element. Just put your whole JS code inside a function which will be called when the window gets loaded.

You can also put your Javascript code below the html.

Respondent: Ajit Kumar

Solution #7:

script is loading before body, keep script after body

Respondent: Sagar M

Solution #8:

Thanks to @Rob M. for his help. This is what the final block of code looked like:

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;
  };
}
Respondent: morocklo

Solution #9:

I simply added ‘async’ to my script tag, which seems to have fixed the issue. I’m not sure why, if someone can explain, but it worked for me. My guess is that the page isn’t waiting for the script to load, so the page loads at the same time as the JavaScript.

Async/Await enables us to write asynchronous code in a synchronous fashion. it’s just syntactic sugar using generators and yield statements to “pause” execution, giving us the ability to assign it to a variable!

Here’s reference link- https://medium.com/siliconwat/how-javascript-async-await-works-3cab4b7d21da

Respondent: Andy Smith

Solution #10:

I encountered the same problem and checked for null but it did not help. Because the script was loading before page load. So just by placing the script before the end body tag solved the problem.

Respondent: Mahmud

Solution #11:

I had the same problem, but my id was present. So I tried adding “window.onload = init;” Then I wrapped my original JS code with an init function (call it what you want). This worked, so at least in my case, I was adding an event listener before my document loaded. This could be what you are experiencing as well.

Respondent: ultrageek

Solution #12:

As others have said problem is that script is executed before the page (and in particular the target element) is loaded.

But I don’t like the solution of reordering the content.

Preferred solution is to put an event handler on page onload event and set the Listener there. That will ensure the page and the target element is loaded before the assignment is executed. eg

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

    <body onload="onLoadFunct()" ....>
    .....
Respondent: pjm

Solution #13:

I’ve a collection of quotes along with names. I’m using update button to update the last quote associated with a specific name but on clicking update button it’s not updating. I’m including code below for server.js file and external js file (main.js).

main.js (external js)

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);
})
})
}

server.js file

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);
  })

})
Respondent: Ambreen Fatima

Solution #14:

This is because the element hadn’t been loaded at the time when the bundle js was being executed.

I’d move the <script src="https://www.py4u.net/discuss/sample.js" type="text/javascript"></script> to the very bottom of the index.html file. This way you can ensure script is executed after all the html elements have been parsed and rendered .

Respondent: Xcode

Solution #15:

Add all event listeners when a window loads.Works like a charm no matter where you put script tags.

window.addEventListener("load", startup);

function startup() {

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

}

myFunc(){}
Respondent: Natalie Jimenez

The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Most Popular

To Top
India and Pakistan’s steroid-soaked rhetoric over Kashmir will come back to haunt them both clenbuterol australia bossier man pleads guilty for leadership role in anabolic steriod distribution conspiracy