I am a complete and utter beginner making a simple calculator. The HTML file has two text fields (a number is entered in each) and one drop down selector with four options (add, subtract, multiply, divide). A JavaScript file is supposed to, on the press of a button, take the numbers entered into the fields plus the type of mathematical operation from the drop-down menu, perform the operation, and insert the result into a span element in the HTML page. When I try to run it and click the button the browser console says Uncaught TypeError: Cannot read properties of undefined (reading 'span') at HTMLButtonElement.<anonymous> (VM82 hopelessJS.js:11:20)
.
Code:
'use strict';
const calcButton = document.querySelector('button');
calcButton.addEventListener('click', function(evt) {
var operation = document.querySelector('select').options.selectedIndex;
var num1 = document.querySelectorAll('input')[0].value;
var num2 = document.querySelectorAll('input')[1].value;
if (operation == 0)
document.body.p.span.innerHTML = num1 + num2; //apparently sth in this syntax is wrong?
else if (operation == 1)
document.body.p.span.innerHTML = num1 - num2;
else if (operation == 2)
document.body.p.span.innerHTML = num1 * num2;
else if (operation == 3)
document.body.p.span.innerHTML = num1 / num2;
});
body {
font-family: sans-serif;
}
input {
margin: 10px;
}
button {
border: 1px solid;
width: 180px;
padding: 8px;
text-align: center;
margin: 10px;
}
span {
font-weight: bold;
}
<body>
<h1>Hopeless Calculator</h1>
<input type="text">
<select>
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input type="text">
<br>
<button type="button">Calculate: </button>
<br>
<p>Result: <span></span></p> //where I want the result inserted
</body>
>Solution :
You can’t get the <span>
element by using those nonexistent properties. First, think about it. If document.body
had two <p>
s, then which would be document.body.p
?
Instead, the DOM API uses .querySelector()
and .querySelectorAll()
to get elements with CSS selectors (there’s also .getElementById()
, .getElementsByClassName()
, etc.). The CSS selector for the <span>
child of the <p>
in the body is body>p>span
. Because you only want to get one element, you’d use .querySelector()
. Like this:
'use strict';
const calcButton = document.querySelector('button');
calcButton.addEventListener('click', function(evt) {
var operation = document.querySelector('select').options.selectedIndex;
var num1 = document.querySelectorAll('input')[0].value;
var num2 = document.querySelectorAll('input')[1].value;
const out = document.querySelector('body>p>span');
if (operation == 0)
out.innerHTML = num1 + num2; //apparently sth in this syntax is wrong?
else if (operation == 1)
out.innerHTML = num1 - num2;
else if (operation == 2)
out.innerHTML = num1 * num2;
else if (operation == 3)
out.innerHTML = num1 / num2;
});
body {
font-family: sans-serif;
}
input {
margin: 10px;
}
button {
border: 1px solid;
width: 180px;
padding: 8px;
text-align: center;
margin: 10px;
}
span {
font-weight: bold;
}
<body>
<h1>Hopeless Calculator</h1>
<input type="text">
<select>
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input type="text">
<br>
<button type="button">Calculate: </button>
<br>
<p>Result: <span></span></p> //where I want the result inserted
</body>