Cannot read property 'addEventListener' of null

JavascriptFunctionGetelementbyidAddeventlistener

Javascript Problem Overview


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.

Javascript Solutions


Solution 1 - Javascript

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

Solution 2 - Javascript

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

Solution 3 - Javascript

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.

Solution 4 - Javascript

script is loading before body, keep script after body

Solution 5 - Javascript

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.

Solution 6 - Javascript

Put script at the end of body tag.

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

Solution 7 - Javascript

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.

Solution 8 - Javascript

This question already has an answer but what i like to do for those simple conditions is using the logical AND (&&) operator :

var el = document.getElementById('overlayBtn');

el && el.addEventListener('click', swapper, false);

More readable and concise in my opinion.

Solution 9 - Javascript

Your script is probably placed in the head tag of HTML and is loading before the DOM loads. There can be two solutions to this:

  1. Place the script tag just before the closing body tag (</body>).

  2. Add the async keyword to your script tag.

> script async src="script.js">

Note: Stackoverflow is not allowing to add script tag code here for security reasons. Add opening and closing parenthesis to the code above.

With async, the file gets downloaded asynchronously and then executed as soon as it's downloaded.

I prefer 2nd option better. Read more about async and defer here

Solution 10 - Javascript

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

Solution 11 - Javascript

Use this way if your js code is the external file:

<script src="filename.js" defer></script>

Either if your code is the internal file, use DOMContentLoaded

Two ways above will make sure that DOM fully loads before executing js code!

Solution 12 - Javascript

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.

Solution 13 - Javascript

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.

Solution 14 - Javascript

You could add the attribute defer to your script tag. The reason why you're seeing that error is because the script is running before the DOM is loading.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="css/styles.css">
    <script src="scripts/main.js" defer="defer"></script>
</head>

Defer is a boolean value that indicates to run script once the DOM has been parsed

Solution 15 - Javascript

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

})

Solution 16 - Javascript

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

Solution 17 - Javascript

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()" ....>
    .....

Solution 18 - Javascript

I got this issue recently, and I found I was providing a wrong classname in getElementById and querySelector. So, I will suggest to also cross-check your class and id names in your script and html file.

Solution 19 - Javascript

I faced this problem when I tried to get an element by Id which was a class. Check and confirm that the your getting the element by the correct attribute e.g id or class. else you will have this error

Solution 20 - Javascript

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="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 .

Solution 21 - Javascript

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(){}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmorockloView Question on Stackoverflow
Solution 1 - JavascriptRob M.View Answer on Stackoverflow
Solution 2 - JavascriptDilip AghedaView Answer on Stackoverflow
Solution 3 - JavascriptsridharView Answer on Stackoverflow
Solution 4 - JavascriptSagar MView Answer on Stackoverflow
Solution 5 - JavascriptMattSidorView Answer on Stackoverflow
Solution 6 - Javascriptmatak8sView Answer on Stackoverflow
Solution 7 - JavascriptAjit KumarView Answer on Stackoverflow
Solution 8 - JavascriptManelView Answer on Stackoverflow
Solution 9 - JavascriptGauravView Answer on Stackoverflow
Solution 10 - JavascriptmorockloView Answer on Stackoverflow
Solution 11 - JavascriptHuy NguyenView Answer on Stackoverflow
Solution 12 - JavascriptultrageekView Answer on Stackoverflow
Solution 13 - JavascriptMahmudView Answer on Stackoverflow
Solution 14 - Javascriptharjit.kainth7View Answer on Stackoverflow
Solution 15 - JavascriptAmbreen FatimaView Answer on Stackoverflow
Solution 16 - JavascriptAndy SmithView Answer on Stackoverflow
Solution 17 - JavascriptpjmView Answer on Stackoverflow
Solution 18 - JavascriptRaunak HajelaView Answer on Stackoverflow
Solution 19 - Javascripttimothy inioluwaView Answer on Stackoverflow
Solution 20 - JavascriptXcodeView Answer on Stackoverflow
Solution 21 - JavascriptNatalie JimenezView Answer on Stackoverflow