Home > Software engineering >  When I click a button on a webpage, how to pass the value of that button as a parameter of a functio
When I click a button on a webpage, how to pass the value of that button as a parameter of a functio

Time:06-17

So I'm working in a project recently it is about the rock paper scissor game. I'm stuck in a problem that when I click on one of the three buttons (which are rock, paper, or scissors) the addEventListener does work but one of the actual parameters of a function that I'm passing as a parameter to the event listener "the console said it is undefined".

I just want when clicking the button to pass the value of that button to this parameter I'm talking about.

const rock = document.querySelector('.rock');
const paper = document.querySelector('.paper');
const scissors = document.querySelector('.scissors');
// there are some functions
let computerSelection = computerPlay();

rock.addEventListener('click', function(){
playRound(playerSelection, computerSelection);
});

paper.addEventListener('click', function(){
playRound(playerSelection, computerSelection);});

scissors.addEventListener('click', function(){
playRound(playerSelection, computerSelection);});
<button >ROCK</button>
<button >PAPER</button>
<button >SCISSORS</button>

CodePudding user response:

You have to read the event on each click listener and you can extract the value from the event by ev.target.value:

anyButton.addEventListener('click', function(ev) { 
  playRound(playerSelection, computerSelection, ev.target.value);
}

This, of course, implies that your buttons all have a value attribute set.

As an improvement, you could add add event listeners at once without going through each element:

const allButtons = document.querySelectorAll('button') // adjust this per your DOM
allButtons.forEach((button) => {
  button.addEventListener('click', function(ev) { 
    playRound(playerSelection, computerSelection, ev.target.value);
  })
})

CodePudding user response:

I think it would be most clean to use the dataset and event delegation.

// use event delegation to to reduce the number of event listeners
document.getElementById("game-inputs").onclick = ({ target }) => {

  // if its not a game button, do nothing
  if (!target.classList.contains("game-button")) {
    return
  }

  // otherwise get the value from the dataset
  const value = target.dataset.value
  console.log(value);
};
<div id="game-inputs">
  <button data-value="rock" >ROCK</button>
  <button data-value="paper" >PAPER</button>
  <button data-value="scissors" >SCISSORS</button>
</div>

CodePudding user response:

You have to pass playSelection according to wich button the player has clicked:

rock.addEventListener('click', function(){
playRound('rock', computerSelection);
});

paper.addEventListener('click', function(){
playRound('paper', computerSelection);});

scissors.addEventListener('click', function(){
playRound('scissors', computerSelection);
});

But I have a suggestion to do that with only one event handler. First you'll have to say in each button what choice it represents. Do that using data- attributtes (https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes):

<button  data-choice="rock">ROCK</button>
<button  data-choice="paper">PAPER</button>
<button  data-choice="scissors">SCISSORS</button>

Note that I added a choice-button class to each button, so you can access all three at once when adding the event:

// there are some functions
let computerSelection = computerPlay();

document.querySelectorAll('.choice-button')
        .forEach(el => el.addEventListener('click', function(event) {
            playRound(event.target.dataset.choice, computerSelection);
         }));

First I use querySelectorAll to find all elements that matches the choice-button class, then i use forEach function to iterate trought all 3 found buttons and add the same event listener to all of them.

Once the event listener is executed, I used 'event.target' to get access to the clicked button, and called the dataset property to get the value defined in the data-choice attribute.

I know it might seem a bit overhead for only three choices, but since you seem to be learning javascript, its interesting to learn different approaches that might help you in a more complex situation.

CodePudding user response:

The undefined error (and two more that follow it once the initial one is fixed) is caused because you are referencing a function that has not been declared:

let computerSelection = computerPlay();
// computerPlay() is not defined;

If you create the computerPlay() function, the error will go away but a new one will appear because playRound() is also not defined. Again, the function must be declared if it is referenced (although hoisting allows it to be declared after the call in this case).

When that is fixed, the last error arises by the reference to playerSelection as, again, this has not been declared. Assuming the value of playerSelection is to be rock, paper, or scissors, you have to extract it from the click event.

The event handler needs to extract the innerText property value of the event's target. Inside you're event listeners you need:

playerSelection = event.target.innerText;
  • Related