I really don't know why this isn't working. In my HTML, if I put my script in the head section, I get the following error in my console:
Uncaught TypeError: Cannot read property 'addEventListener' of null
If I put my script in the bottom part of the body, it's working fine.
HTML :
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="script.js"> </script>
</head>
<body>
<ul>
<li><a href="#" data-img="img1" id="img1"> Shahin </a></li>
<li><a href="#" data-img="img2" id="img2"> Lina </a></li>
<li><a href="#" data-img="img3" id="img3"> Adrita </a></li>
</ul>
<img src="./img/1.jpg" class="hidden">
<img src="./img/2.png" class="hidden">
<img src="./img/3.jpg" class="hidden">
</body>
JavaScript :
var shahin = document.getElementById('img1');
var lina = document.getElementById('img2');
var adrita = document.getElementById("img3");
shahin.addEventListener('click',picShow);
lina.addEventListener('click',picShow);
adrita.addEventListener('click',picShow);
function picShow() {
console.log(this);
}
Can anybody tell me what I'm doing wrong and where is the proper place to put the script tag? Also, what change should I make to run my script from head section? I will be glad for your answer. Thanks in advance
I really don't know why this isn't working. In my HTML, if I put my script in the head section, I get the following error in my console:
Uncaught TypeError: Cannot read property 'addEventListener' of null
If I put my script in the bottom part of the body, it's working fine.
HTML :
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="script.js"> </script>
</head>
<body>
<ul>
<li><a href="#" data-img="img1" id="img1"> Shahin </a></li>
<li><a href="#" data-img="img2" id="img2"> Lina </a></li>
<li><a href="#" data-img="img3" id="img3"> Adrita </a></li>
</ul>
<img src="./img/1.jpg" class="hidden">
<img src="./img/2.png" class="hidden">
<img src="./img/3.jpg" class="hidden">
</body>
JavaScript :
var shahin = document.getElementById('img1');
var lina = document.getElementById('img2');
var adrita = document.getElementById("img3");
shahin.addEventListener('click',picShow);
lina.addEventListener('click',picShow);
adrita.addEventListener('click',picShow);
function picShow() {
console.log(this);
}
Can anybody tell me what I'm doing wrong and where is the proper place to put the script tag? Also, what change should I make to run my script from head section? I will be glad for your answer. Thanks in advance
Share Improve this question edited May 2, 2019 at 12:39 b3nThomas 476 bronze badges asked Nov 30, 2017 at 19:51 Sanjida linaSanjida lina 1232 silver badges11 bronze badges 4-
1
The DOM has to load for you to be able to grab the elements and attach listeners. If your code is in the head, the DOM hasn't loaded before the script is run. Either wrap your code in a
onload
or ready wrapper, or move your code under the HTML – Andy Commented Nov 30, 2017 at 19:55 -
you need to put it in a
$(document).ready()
if it's in the head because your body hasn't been rendered yet when you add the handler – jdubjdub Commented Nov 30, 2017 at 19:55 - @jdubjdub, that would only work with jQuery. – Andy Commented Nov 30, 2017 at 19:56
- whatever ready state thing you want to use is fine - just something that runs after the DOM is loaded – jdubjdub Commented Nov 30, 2017 at 19:58
4 Answers
Reset to default 3Your script is loading and being executed prior to the rest of the body HTML, so naturally, document.getElementById
is going to return null.
You should be running your event listener subscription code on or after the document.ready
event.
Wrap the code you posted into a JS function, then set that function as the callback to be executed on document.ready:
document.addEventListener('load', initFn);
<script type="text/javascript" defer src="script.js"> </script>
Add key word defer, script runs when all DOM elements will loaded
If you put your <script>
in the <head>
javascript loading from top to bottom.
So when loading it returns undefined eventlistener.
So try use the script just before the end of your </body>
tag and it will works.
Like so:
<script type="text/javascript" src="script.js"> </script>
</body>
Further to Josh E's answer:
You should be running your event listener subscription code on or after the document.ready event
If you want to execute your code as soon as the element is available, you can use requestAnimationFrame
to scan the DOM during page load instead of waiting for the entire page to load:
function doSomethingWithElement(myElement) {
myElement.addEventListener('click', function() {
// Do stuff here
});
}
function searchForElement() {
const el = document.getElementById('img1');
if (el) {
return doSomethingWithEl(el);
}
window.searchID = window.requestAnimationFrame(searchForElement);
}
// Store the request ID so it can be cancelled later
// Otherwise it'll run forever!
window.searchID = window.requestAnimationFrame(searchForElement);
window.addEventListener('load', function() {
window.cancelAnimationFrame(window.searchID);
});
This might be overkill but it's super useful when you want to manipulate or add listeners to DOM elements as soon as is possible.