问题
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.
回答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);
}
回答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>");
}
回答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.
回答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.
回答5:
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.
回答6:
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;
};
}
回答7:
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
回答8:
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()" ....>
.....
回答9:
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);
})
})
回答10:
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 .
回答11:
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(){}
来源:https://stackoverflow.com/questions/26107125/cannot-read-property-addeventlistener-of-null