I was trying to make a tally counter with buttons but when i press the button i get this error:
Uncaught TypeError: Cannot set properties of null (setting 'innerText')
Here is my HTML code:
<!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>
<script src=./test.js></script>
<link rel="stylesheet" href=./test.css></link>
</head>
<body>
<h1 id="count_el">0</h1>
<button id="increase" onclick="increase()">INCREASE</button>
<button id="decrease" onclick="decrease()">DECREASE</button>
</body>
</html>
And here is my JavaScript code:
const count_el = document.getElementById("count_el")
let count = 0
function increase(){
count += 1
count_el.innerText = count
}
function decrease(){
count -= 1
count_el.innerText = count
}
Try and add defer into your script tag like so:
<script src=./test.js defer></script>
this will make the javascript load after the page has loaded and then the error should disappear.
I assume the problem with your code is that the script runs before the dom has been loaded, so I've edited it to run after the page has been loaded. I've also added the event listeners using javascript instead of html.
if (document.readyState === "complete") onLoad();
else addEventListener("load", onLoad);
function onLoad() {
const countDom = document.querySelector("#count_el"),
increaseButton = document.querySelector("#increase"),
decreaseButton = document.querySelector("#decrease");
let count = 0;
increaseButton.addEventListener("click", increase);
decreaseButton.addEventListener("click", decrease);
function increase() {
count += 1;
countDom.innerText = count;
}
function decrease() {
count -= 1;
countDom.innerText = count;
}
}
<!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>
<script src=./test.js></script>
<link rel="stylesheet" href=./test.css></link>
</head>
<body>
<h1 id="count_el">0</h1>
<button id="increase">INCREASE</button>
<button id="decrease">DECREASE</button>
</body>
</html>
You could also just move your scripts to the end of the body instead of inside the head but it's better to have safe scripts that will run regardless of the position and state of the script.
It seems the only problem is the loading phase of your javascript code: When trying to call document.getElementById('count_el') it can't find such element because it is not loaded in the DOM, so to avoid that you can use the defer attribute in your script tag.
There are three main ways to load an external js script, and I quote:
- If
asyncis present: The script is downloaded in parallel to parsing the page, and executed as soon as it is available (before parsing completes)- If
deferis present (and notasync): The script is downloaded in parallel to parsing the page, and executed after the page has finished parsing- If neither
asyncordeferis present: The script is downloaded and executed immediately, blocking parsing until the script is completed
const count_el = document.getElementById("count_el")
let count = 0
function increase(){
count += 1
count_el.innerText = count
}
function decrease(){
count -= 1
count_el.innerText = count
}
<!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>
<script src=./test.js defer></script>
<link rel="stylesheet" href=./test.css></link>
</head>
<body>
<h1 id="count_el">0</h1>
<button id="increase" onclick="increase()">INCREASE</button>
<button id="decrease" onclick="decrease()">DECREASE</button>
</body>
</html>