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.
This question is related to
javascript
function
getelementbyid
addeventlistener
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
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.
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.
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()" ....>
.....
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.
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.
Put script at the end of body tag.
<html>
<body>
.........
<script src="main.js"></script>
</body>
</html>
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 .
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(){}
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;
};
}
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.
Thanks from all, Load the Scripts in specific pages that you use, not for all pages, sometimes using swiper.js or other library it may cause this error message, the only way to solve this issue it to load the JS library on specific pages that ID is exist and prevent loading of the same library in all pages.
Hope this help you.
script is loading before body, keep script after content
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).
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);
})
})
}
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);
})
})
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>");
}
Source: Stackoverflow.com