在递归后多次触发addEventListener
我还是个新手,我正在制作一个简单的石头、布、剪刀游戏。我正在使用addEventListener等待岩石按钮、布按钮或剪刀按钮被按下,然后它将执行游戏。问题是,当我按下重新启动游戏按钮并开始一个新游戏时,addEventListener中的按钮单击函数被执行两次。所以它只需点击一次按钮就可以播放这一轮两次。如果我再次重新启动游戏,则addEventListener函数将执行3次,依此类推。重新启动函数将分数重置为0并调用main()游戏函数。我认为这个问题与在Restart()函数中递归运行main()时再次执行addEventListener有关。我如何修复此问题?
数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">const myScoreLabel = document.querySelector('.myScore');
const compScoreLabel = document.querySelector('.compScore');
const resultLabel = document.querySelector('.result');
const winnerLabel = document.querySelector('.winner');
let myscore = 0;
let computerscore = 0;
function computerPlay() {
let choices = ["Rock", "Paper", "Scissors"];
let index = Math.floor(Math.random() * 3);
let move = choices[index];
return move;
}
function playRound(playerSelection, computerSelection) {
let player = playerSelection.toLowerCase();
let computer = computerSelection.toLowerCase();
switch(player) {
case "rock":
switch(computer){
case "rock":
return "Draw! Try again...";
break;
case "paper":
return "You lose! Try again...";
break;
case "scissors":
return "You win!";
break;
}
break;
case "paper":
switch(computer){
case "rock":
return "You win!";
break;
case "paper":
return "Draw! Try again...";
break;
case "scissors":
return "You lose! Try again...";
break;
}
break;
case "scissors":
switch(computer){
case "rock":
return "You lose! Try again...";
break;
case "paper":
return "You win!";
break;
case "scissors":
return "Draw! Try again...";
break;
}
break;
}
}
function main() {
myScoreLabel.textContent = myscore;
compScoreLabel.textContent = computerscore;
resultLabel.textContent = "";
winnerLabel.textContent = "";
const buttons = document.querySelectorAll('button');
buttons.forEach((button) => {
button.addEventListener('click', function() {
let playerSelection = this.value;
let computerSelection = computerPlay();
let result = playRound(playerSelection, computerSelection);
const resultLabel = document.querySelector('.result');
resultLabel.textContent = result;
console.log(result);
if(result == "You win!") { //Win
myscore++;
myScoreLabel.textContent = myscore.toString();
console.log("Your score: " + myscore);
console.log("Computer's score: " + computerscore);
console.log("");
if(myscore == 5){
winnerLabel.textContent = "You won the game!";
alert("Click Restart to play a new game");
}
}
else if(result == "You lose! Try again..."){ //Lose
computerscore++;
compScoreLabel.textContent = computerscore.toString();
console.log("Your score: " + myscore);
console.log("Computer's score: " + computerscore);
console.log("");
if(computerscore == 5) {
winnerLabel.textContent = "You lost the game!";
alert("Click Restart to play a new game");
}
}
else{ //Draw
console.log("Your score: " + myscore);
console.log("Computer's score: " + computerscore);
console.log("");
}
});
});
}
function restart() {
myscore = 0;
computerscore = 0;
main();
}
main();
<div class="score">
<h2 class="myScore"></h2>
<span>:</span>
<h2 class="compScore"></h2>
</div>
<div class="choice">
<button class="rock" value="rock">
Rock
</button>
<button class="paper" value="paper">
Paper
</button>
<button class="scissors" value="scissors">
Scissors
</button>
<input id="restartSettings" type="button" value="Restart" onclick="restart()" />
</div>
<h2 class="result"></h2>
<h1 class="winner"></h1>
编辑:如果运行代码片段,可以看到在单击Restart之后,按钮addEventListener内的代码被执行两次。
解决方案
每次您调用main()
时,它会再次添加事件监听器,这意味着单击这些按钮将导致事件多次触发。
在添加事件侦听器之前删除它们,或者只在main()
之外添加一次。
相关文章