在 DOM / JavaScript 中将(附加)数据传递给事件处理程序的可能方式有哪些?
What are possible ways of passing (additional) data to an event-handler in DOM / JavaScript?
当 运行在 Firefox 上以开发人员模式运行时,我收到错误消息,“未捕获的类型错误:EventTarget.addEventListener:参数 2 不是对象。”
我想要做的是在传递值“rock”时使用“playRound()”函数运行。
在解决问题时,我在 playRound() 函数中放置了一个 console.log,并注意到它 运行 甚至在被告知“点击”操作之前就已完成。点击甚至不会触发任何东西。
这是我到目前为止的想法...
function computerPlay () {
let computerSelection = '';
let randomInt = Math.floor(Math.random() * 3);
if (randomInt === 0) {
computerSelection = 'Rock';
} else if (randomInt === 1) {
computerSelection = 'Paper';
} else {
computerSelection = 'Scissors';
}
return computerSelection;
}
function playRound (playerSelection) {
let roundWinner = '';
let computerSelection = computerPlay();
if (playerSelection === computerSelection) {
roundWinner = "It's a tie!";
} else if (playerSelection == 'Rock' && computerSelection == 'Scissors'){
roundWinner = "You win! Rock beats scissors!";
} else if (playerSelection == 'Rock' && computerSelection == 'Paper'){
roundWinner = "You lose! Paper beats rock!";
} else if (playerSelection == 'Paper' && computerSelection == 'Rock'){
roundWinner = "You win! Paper beats rock!";
} else if (playerSelection == 'Paper' && computerSelection == 'Scissors'){
roundWinner = "You lose! Scissors beats paper!";
} else if (playerSelection == 'Scissors' && computerSelection == 'Paper'){
roundWinner = "You win! Scissors beats paper!";
} else if (playerSelection == 'Scissors' && computerSelection == 'Rock') {
roundWinner = "You lose! Rock beats scissors!";
}
console.log('TEST');
return roundWinner;
}
const rock = document.querySelector("#rock");
const paper = document.querySelector("#paper");
const scissors = document.querySelector("#scissors");
rock.addEventListener("click", playRound("rock"));
<button id="rock" value="rock">Rock</button>
<button id="paper" value="paper">Paper</button>
<button id="scissors" value="scissors">Scissors</button>
对于事件侦听器,您需要将函数作为第二个参数传入。目前,您传递的是方法 playRound 的调用返回的值。
将最后一行更改为:
rock.addEventListener("click", () => playRound("rock"));
如果你想使用匿名的ES6箭头函数
rock.addEventListener("click", function() { return playRound("rock") });
如果您更喜欢标准的匿名函数语法。
希望对您有所帮助!
当然要看"TEST"
日志。由于在尝试向 rock
元素添加 event-listener 时调用了 playRound
... rock.addEventListener("click", playRound("rock"))
... 最内层的函数使用 playRound("rock")
执行。因此它将记录,并且它 returns 一个字符串(非常 roundWinner
)。这个字符串值然后将通过例如添加为 rock
元素的处理函数。 ... rock.addEventListener("click", "It's a tie!")
...哪个原因立即失败,因为 addEventListener
的第二个参数需要是可调用函数。
一个可能的解决方案是以这样一种方式实现 handleNextRound
事件处理程序,即从主动点击的元素之一中读取玩家的选择...
function computerPlay() {
return [
'rock',
'paper',
'scissors'
][Math.floor(Math.random() * 3)];
}
function handleNextRound(evt) {
const decisionMap = {
rockscissors: "You win! Rock beats scissors!",
rockpaper: "You lose! Paper beats rock!",
paperrock: "You win! Paper beats rock!",
paperscissors: "You lose! Scissors beats paper!",
scissorspaper: "You win! Scissors beats paper!",
scissorsrock: "You lose! Rock beats scissors!",
scissorsscissors: "It's a tie!",
paperpaper: "It's a tie!",
rockrock: "It's a tie!"
};
const playerSelection = evt.currentTarget.value;
const computerSelection = computerPlay();
console.log('decision :', decisionMap[playerSelection + computerSelection]);
// return decisionMap[playerSelection + computerSelection];
}
const rock = document.querySelector("#rock");
const paper = document.querySelector("#paper");
const scissors = document.querySelector("#scissors");
rock.addEventListener("click", handleNextRound);
paper.addEventListener("click", handleNextRound);
scissors.addEventListener("click", handleNextRound);
<button id="rock" value="rock">Rock</button>
<button id="paper" value="paper">Paper</button>
<button id="scissors" value="scissors">Scissors</button>
我认为不太受欢迎的另一种方法是 bind
玩家选择的值作为处理函数的参数 ([[BoundArguments]]
) ...
function computerPlay() {
return [
'rock',
'paper',
'scissors'
][Math.floor(Math.random() * 3)];
}
function handleNextRoundWithBoundSelection(playerSelection, evt) {
const decisionMap = {
rockscissors: "You win! Rock beats scissors!",
rockpaper: "You lose! Paper beats rock!",
paperrock: "You win! Paper beats rock!",
paperscissors: "You lose! Scissors beats paper!",
scissorspaper: "You win! Scissors beats paper!",
scissorsrock: "You lose! Rock beats scissors!",
scissorsscissors: "It's a tie!",
paperpaper: "It's a tie!",
rockrock: "It's a tie!"
};
const computerSelection = computerPlay();
console.log('(evt.currentTarget === this) ?', (evt.currentTarget === this));
console.log('decision :', decisionMap[playerSelection + computerSelection]);
}
const rock = document.querySelector("#rock");
const paper = document.querySelector("#paper");
const scissors = document.querySelector("#scissors");
rock.addEventListener("click", handleNextRoundWithBoundSelection.bind(rock, 'rock'));
paper.addEventListener("click", handleNextRoundWithBoundSelection.bind(paper, 'paper'));
scissors.addEventListener("click", handleNextRoundWithBoundSelection.bind(scissors, 'scissors'));
<button id="rock">Rock</button>
<button id="paper">Paper</button>
<button id="scissors">Scissors</button>
其他人已经建议了第三个选项,...提供处理函数作为(匿名)function expression, either as arrow function 或经典...
function computerPlay() {
return [
'rock',
'paper',
'scissors'
][Math.floor(Math.random() * 3)];
}
function handleNextRound(playerSelection/*, evt*/) {
const decisionMap = {
rockscissors: "You win! Rock beats scissors!",
rockpaper: "You lose! Paper beats rock!",
paperrock: "You win! Paper beats rock!",
paperscissors: "You lose! Scissors beats paper!",
scissorspaper: "You win! Scissors beats paper!",
scissorsrock: "You lose! Rock beats scissors!",
scissorsscissors: "It's a tie!",
paperpaper: "It's a tie!",
rockrock: "It's a tie!"
};
const computerSelection = computerPlay();
// console.log('(evt.currentTarget.value === "") ?', (evt.currentTarget.value === ""));
console.log('decision :', decisionMap[playerSelection + computerSelection]);
}
const rock = document.querySelector("#rock");
const paper = document.querySelector("#paper");
const scissors = document.querySelector("#scissors");
rock.addEventListener("click", function () { handleNextRound('rock'); });
paper.addEventListener("click", (/*evt*/) => handleNextRound('paper'/*, evt*/));
scissors.addEventListener("click", () => handleNextRound('scissors'));
<button id="rock">Rock</button>
<button id="paper">Paper</button>
<button id="scissors">Scissors</button>
当 运行在 Firefox 上以开发人员模式运行时,我收到错误消息,“未捕获的类型错误:EventTarget.addEventListener:参数 2 不是对象。”
我想要做的是在传递值“rock”时使用“playRound()”函数运行。
在解决问题时,我在 playRound() 函数中放置了一个 console.log,并注意到它 运行 甚至在被告知“点击”操作之前就已完成。点击甚至不会触发任何东西。
这是我到目前为止的想法...
function computerPlay () {
let computerSelection = '';
let randomInt = Math.floor(Math.random() * 3);
if (randomInt === 0) {
computerSelection = 'Rock';
} else if (randomInt === 1) {
computerSelection = 'Paper';
} else {
computerSelection = 'Scissors';
}
return computerSelection;
}
function playRound (playerSelection) {
let roundWinner = '';
let computerSelection = computerPlay();
if (playerSelection === computerSelection) {
roundWinner = "It's a tie!";
} else if (playerSelection == 'Rock' && computerSelection == 'Scissors'){
roundWinner = "You win! Rock beats scissors!";
} else if (playerSelection == 'Rock' && computerSelection == 'Paper'){
roundWinner = "You lose! Paper beats rock!";
} else if (playerSelection == 'Paper' && computerSelection == 'Rock'){
roundWinner = "You win! Paper beats rock!";
} else if (playerSelection == 'Paper' && computerSelection == 'Scissors'){
roundWinner = "You lose! Scissors beats paper!";
} else if (playerSelection == 'Scissors' && computerSelection == 'Paper'){
roundWinner = "You win! Scissors beats paper!";
} else if (playerSelection == 'Scissors' && computerSelection == 'Rock') {
roundWinner = "You lose! Rock beats scissors!";
}
console.log('TEST');
return roundWinner;
}
const rock = document.querySelector("#rock");
const paper = document.querySelector("#paper");
const scissors = document.querySelector("#scissors");
rock.addEventListener("click", playRound("rock"));
<button id="rock" value="rock">Rock</button>
<button id="paper" value="paper">Paper</button>
<button id="scissors" value="scissors">Scissors</button>
对于事件侦听器,您需要将函数作为第二个参数传入。目前,您传递的是方法 playRound 的调用返回的值。
将最后一行更改为:
rock.addEventListener("click", () => playRound("rock"));
如果你想使用匿名的ES6箭头函数
rock.addEventListener("click", function() { return playRound("rock") });
如果您更喜欢标准的匿名函数语法。
希望对您有所帮助!
当然要看"TEST"
日志。由于在尝试向 rock
元素添加 event-listener 时调用了 playRound
... rock.addEventListener("click", playRound("rock"))
... 最内层的函数使用 playRound("rock")
执行。因此它将记录,并且它 returns 一个字符串(非常 roundWinner
)。这个字符串值然后将通过例如添加为 rock
元素的处理函数。 ... rock.addEventListener("click", "It's a tie!")
...哪个原因立即失败,因为 addEventListener
的第二个参数需要是可调用函数。
一个可能的解决方案是以这样一种方式实现 handleNextRound
事件处理程序,即从主动点击的元素之一中读取玩家的选择...
function computerPlay() {
return [
'rock',
'paper',
'scissors'
][Math.floor(Math.random() * 3)];
}
function handleNextRound(evt) {
const decisionMap = {
rockscissors: "You win! Rock beats scissors!",
rockpaper: "You lose! Paper beats rock!",
paperrock: "You win! Paper beats rock!",
paperscissors: "You lose! Scissors beats paper!",
scissorspaper: "You win! Scissors beats paper!",
scissorsrock: "You lose! Rock beats scissors!",
scissorsscissors: "It's a tie!",
paperpaper: "It's a tie!",
rockrock: "It's a tie!"
};
const playerSelection = evt.currentTarget.value;
const computerSelection = computerPlay();
console.log('decision :', decisionMap[playerSelection + computerSelection]);
// return decisionMap[playerSelection + computerSelection];
}
const rock = document.querySelector("#rock");
const paper = document.querySelector("#paper");
const scissors = document.querySelector("#scissors");
rock.addEventListener("click", handleNextRound);
paper.addEventListener("click", handleNextRound);
scissors.addEventListener("click", handleNextRound);
<button id="rock" value="rock">Rock</button>
<button id="paper" value="paper">Paper</button>
<button id="scissors" value="scissors">Scissors</button>
我认为不太受欢迎的另一种方法是 bind
玩家选择的值作为处理函数的参数 ([[BoundArguments]]
) ...
function computerPlay() {
return [
'rock',
'paper',
'scissors'
][Math.floor(Math.random() * 3)];
}
function handleNextRoundWithBoundSelection(playerSelection, evt) {
const decisionMap = {
rockscissors: "You win! Rock beats scissors!",
rockpaper: "You lose! Paper beats rock!",
paperrock: "You win! Paper beats rock!",
paperscissors: "You lose! Scissors beats paper!",
scissorspaper: "You win! Scissors beats paper!",
scissorsrock: "You lose! Rock beats scissors!",
scissorsscissors: "It's a tie!",
paperpaper: "It's a tie!",
rockrock: "It's a tie!"
};
const computerSelection = computerPlay();
console.log('(evt.currentTarget === this) ?', (evt.currentTarget === this));
console.log('decision :', decisionMap[playerSelection + computerSelection]);
}
const rock = document.querySelector("#rock");
const paper = document.querySelector("#paper");
const scissors = document.querySelector("#scissors");
rock.addEventListener("click", handleNextRoundWithBoundSelection.bind(rock, 'rock'));
paper.addEventListener("click", handleNextRoundWithBoundSelection.bind(paper, 'paper'));
scissors.addEventListener("click", handleNextRoundWithBoundSelection.bind(scissors, 'scissors'));
<button id="rock">Rock</button>
<button id="paper">Paper</button>
<button id="scissors">Scissors</button>
其他人已经建议了第三个选项,...提供处理函数作为(匿名)function expression, either as arrow function 或经典...
function computerPlay() {
return [
'rock',
'paper',
'scissors'
][Math.floor(Math.random() * 3)];
}
function handleNextRound(playerSelection/*, evt*/) {
const decisionMap = {
rockscissors: "You win! Rock beats scissors!",
rockpaper: "You lose! Paper beats rock!",
paperrock: "You win! Paper beats rock!",
paperscissors: "You lose! Scissors beats paper!",
scissorspaper: "You win! Scissors beats paper!",
scissorsrock: "You lose! Rock beats scissors!",
scissorsscissors: "It's a tie!",
paperpaper: "It's a tie!",
rockrock: "It's a tie!"
};
const computerSelection = computerPlay();
// console.log('(evt.currentTarget.value === "") ?', (evt.currentTarget.value === ""));
console.log('decision :', decisionMap[playerSelection + computerSelection]);
}
const rock = document.querySelector("#rock");
const paper = document.querySelector("#paper");
const scissors = document.querySelector("#scissors");
rock.addEventListener("click", function () { handleNextRound('rock'); });
paper.addEventListener("click", (/*evt*/) => handleNextRound('paper'/*, evt*/));
scissors.addEventListener("click", () => handleNextRound('scissors'));
<button id="rock">Rock</button>
<button id="paper">Paper</button>
<button id="scissors">Scissors</button>