提问人:ESDEE 提问时间:11/8/2023 更新时间:11/11/2023 访问量:27
在重新运行函数之前删除事件侦听器
Removing Event Listeners on before the function is re-run
问:
我想为飞镖创建一个记分板。 在这个游戏中,许多玩家轮流投掷 3 个飞镖。每个飞镖都会获得一定的分数。 我创建了与飞镖板上投掷的实际目标相对应的按钮。 此类按钮的示例: 玩家投掷 1,因此单击此按钮:1。
我的问题是将按钮上的事件侦听器与回合结束时自动切换到下一个玩家相结合。
通过下面的代码,似乎按钮点击仍然与前一个玩家相关联,因此当第二个玩家投掷时,这些投掷也计入第一个玩家......
所以在第一轮之后(每个玩家都投掷了 3 次,所以点击了 12 次按钮,player1 的 totalArrows = 21,这显然是错误的,这应该是 3。
我试图从事件侦听器中提取handleClick函数,但后来我似乎无法将按钮作为参数传递,这是分数所必需的。
我的代码:
// Player
// remaining = how much of the score remains after each throw.
// totalArrows = how many arrows has player thrown.
let player1 = { name: 'Steven', remaining: 501, totalArrows: 0};
let player2 = { name: 'Tom', remaining: 501, totalArrows: 0};
let player3 = { name: 'Nico', remaining: 501, totalArrows: 0};
let players = [player1, player2, player3];
// The buttons that can be clicked for scoring
const targetButtons = document.querySelectorAll(".target");
let playersIndex = 0;
let throws = 0;
function playerTurn() {
let currentPlayer = players[playersIndex];
targetButtons.forEach((button) => {
button.addEventListener('click', function handleClick() {
if (throws < 3 ) {
currentPlayer.totalArrows++;
const scoreThisThrow = parseInt(this.textContent);
currentPlayer.remaining -= scoreThisThrow:
throws++;
if (throws === 3) {
button.removeEventListener("click", handleClick);
playersIndex = (playersIndex + 1) % players.length;
throws = 0;
playerTurn()
}
}
});
});
}
// Start the game
playerTurn()
答:
你的逻辑是关闭的。正如你所拥有的,你只评估当.当然,这永远不会发生:如果小于 3,则永远不能等于 3。因此,请将您从另一个街区中取出。players === 3
players < 3
players
players
if players === 3
if
这应该可以解决您的问题,而不必删除事件侦听器。我也没有看到你对你的财产做了什么。我假设它的使用超出了您在此处定义的问题的范围。但是,如果你使用它只是为了试图弄清楚为什么只有一个球员得到了所有的投掷,那么你可以安全地删除它。totalArrows
顺便说一句,如果你不是专门从你的设置外部调用,你不需要给它一个名字:等等。handleClick
addEventListener
button.addEventListener('click', function(e) {
请注意,通常还会向函数添加参数,通常是 或 。这提供了对元素实现的对象的引用。因此,例如,如果要防止事件的正常行为,可以将 .执行此操作的一个常见示例是,窗体中有一个类型的按钮,并且想要重写该按钮的默认行为。e
event
Event
button
e.preventDefault
submit
评论
preventDefault
Event
if (throws === 3)
if
我已经设法让它工作了。代码绝对需要优化/清理,但游戏在三次投掷后自动进入下一个玩家,没有任何箭头或剩余点问题。
我加入了飞镖 X01 游戏中通常使用的计分系统:
- 当赢得一定数量的盘数时,就赢得了一场比赛。
- 当赢得一定数量的腿时,就赢了一盘。
- 当玩家达到 0 或更低时,将赢得一回合。
代码如下:
// remaining = how much of the score remains after each throw.
// totalArrows = how many arrows has player thrown.
// legs = number of legs won.
// sets = number of sets won.
const player1 = { name: 'Steven', remaining: 501, totalArrows: 0, legs: 0, sets: 0};
const player2 = { name: 'Tom', remaining: 501, totalArrows: 0, legs: 0, sets: 0};
const player3 = { name: 'Nico', remaining: 501, totalArrows: 0, legs: 0, sets: 0};
const players = [player1, player2, player3];
// The buttons that can be clicked for scoring
const targetButtons = document.querySelectorAll(".target");
const numPlayers = players.length;
const totalLegs = 3;
const totalSets = 3;
let playersIndex = 0;
let currentPlayer = players[playersIndex];
let throws = 0;
let gameFinished = false
function playerTurn() {
targetButtons.forEach((button) => {
button.addEventListener('click', function handleClick() {
if (throws < 3 ) {
currentPlayer.totalArrows += 1;
const scoreThisThrow = parseInt(this.textContent);
currentPlayer.remaining -= scoreThisThrow:
throws++;
if (throws === 3 || currentPlayer.remaining < 1) {
// TODO: Bust rule
// TODO: Double out
if (currentPlayer.remaining < 1) { // Player wins leg
currentPlayer.legs += 1;
if (currentPlayer.legs === totalLegs) { // Player wins set
currentPlayer.sets += 1;
// Reset leg count
players.forEach((player) => {
player.legs = 0
});
if (player.sets === totalSets) { // Player wins the game
gameFinished = true;
} else {
playersIndex = (playersIndex + 1) % numPlayers;
currentPlayer = players[playersIndex];
throws = 0;
return;
}
}
playersIndex = (playersIndex + 1) % numPlayers;
currentPlayer = players[playersIndex];
throws = 0;
return;
}
if (throws === 3) {
playersIndex = (playersIndex + 1) % players.length;
currentPlayer = players[playersIndex];
throws = 0;
return;
}
if (!gameFinished) {
playerTurn();
}
}
}
});
});
}
playerTurn()
评论