Reputation: 73
I created buttons with different values in my HTML. I am trying to output these values when clicked on. I am making use of querySelectorAll
and eventListeners but it keeps outputing undefined.
let buttons = document.querySelectorAll('button');
function showNumber() {
if (buttons.value != 5) {
document.getElementById('screen').innerHTML = buttons.value;
} else {
document.getElementById('screen').innerHTML = 5;
}
}
buttons.forEach(buttons => {
buttons.addEventListener("click", () => {
showNumber()
});
});
Upvotes: 7
Views: 8796
Reputation: 6922
The issue is that buttons
is the whole array of buttons, not just the clicked button.
To access the button that was clicked, the simplest way is to use this
. Inside an event handler, this
points to the element that triggered the event (i.e. the button that was clicked), as long as we bind the function showNumber
directly to the event handler (and not calling showNumber()
from an anonymous function like in your initial code), i.e.:
button.addEventListener("click", showNumber);
So, binding showNumber
directly to the event handler and using this
, this is what we can do:
let buttons = document.querySelectorAll('button');
function showNumber() {
document.getElementById('screen').innerHTML = this.value;
}
buttons.forEach(button => {
button.addEventListener("click", showNumber);
});
<p id="screen"></p>
<button value="1">1</button>
<button value="10">10</button>
Edit: Removed unnecessary if statement inside the showNumber
function.
Upvotes: 2
Reputation: 4246
You can do it like this:
const
buttons = document.getElementsByTagName("button"),
screen = document.getElementById('screen');
Array.from(buttons).forEach(button =>
button.addEventListener("click", showNumber));
function showNumber(event) { // Listener can access its triggering event
const button = event.target; // event's `target` property is useful
if (button.value != 5) { screen.innerHTML = button.value; }
else { screen.innerHTML = 5; }
}
<button value="5">Button 1</button>
<button value="42">Button 2</button>
<p id="screen"></p>
But you might consider employing event delegation:
const
container = document.getElementById('container'),
screen = document.getElementById('screen');
container.addEventListener("click", showNumber); // events bubble up to ancestors
function showNumber(event) {
const clickedThing = event.target;
if(clickedThing.tagName == 'BUTTON'){ // makes sure this click interests us
screen.innerHTML = clickedThing.value;
}
}
<div id="container">
<button value="5">Button 1</button>
<button value="42">Button 2</button>
</div>
<p id="screen"></p>
Upvotes: 6
Reputation: 15700
in your foreach loop you need to pass back the button to your function
let buttons = document.querySelectorAll('button');
function showNumber(button) {
if (button.value != 6) {
document.getElementById('screen').innerHTML = button.value;
} else {
document.getElementById('screen').innerHTML = 5;
}
}
buttons.forEach(button => {
button.addEventListener("click", () => {
showNumber(button)
});
});
<button value=10>10</button>
<button value=8>8</button>
<button value=6>6</button>
<button value=4>4</button>
<button value=2>2</button>
<div id='screen'></div>
Upvotes: 3