addEventListener('click', function(), {once: true}) 在同一位置触发多次
addEventListener('click', function(), {once: true}) firing multiple times in the same position
let doorLeft = document.getElementById("left");
let doorMiddle = document.getElementById("middle");
let doorRight = document.getElementById("right");
let resetButton = document.getElementById("reset");
let numberOfClicks = 0;
function incrementClicks() {
numberOfClicks++;
console.log('Number of clicks: ' + numberOfClicks)
}
/* -------------------------------------------------------------------------- */
/* handle click door only once */
/* -------------------------------------------------------------------------- */
const revealDoorColour = () => {
doorLeft.addEventListener(
"click",
() => {
incrementClicks();
}, {
once: true,
}
);
doorMiddle.addEventListener(
"click",
() => {
incrementClicks();
}, {
once: true,
}
);
doorRight.addEventListener(
"click",
() => {
incrementClicks();
}, {
once: true,
}
);
};
/* -------------------------------------------------------------------------- */
const reset = () => {
doorLeft.style.backgroundColor = "paleturquoise";
doorRight.style.backgroundColor = "paleturquoise";
doorMiddle.style.backgroundColor = "paleturquoise";
revealDoorColour();
resetButton.innerHTML = "Let's play";
};
resetButton.addEventListener("click", function() {
reset();
numberOfClicks = 0;
});
.container.main {
display: flex;
justify-content: space-around;
padding: 0 20%;
}
.door {
height: 500px;
width: 300px;
margin: 10px;
}
#left {
background-color: paleturquoise;
}
#middle {
background-color: paleturquoise;
}
#right {
background-color: paleturquoise;
}
.score {
text-align: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
<title>Door guesser</title>
<script src="./js/main.js" async></script>
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<div class="container main">
<div class="door" id="left">
</div>
<div class="door" id="middle">
</div>
<div class="door" id="right">
</div>
</div>
<div class="container score">
<div class="currentScoreGroup">
<div>Current score: </div>
<div id="currentScore">0</div>
</div>
<div class="bestScoreGroup">
<div>Best score: </div>
<div id="bestScore">0</div>
</div>
<button class="reset" id='reset'>Let's play </button>
</div>
</body>
</html>
在 之后,我添加了 {once:true} 参数,它似乎在大多数情况下都能正常工作。但是,当单击有问题的 div 时,它会随机触发多次(在相同的 x/y 坐标处)。这怎么可能?我在匿名函数中设置了一个断点,它多次运行它。有什么想法吗?
重现问题
- 点击开始玩吧
- 点击任意卡片
- 点击让我们再玩一次
- 点击另一张卡片
- 现在您应该在控制台中看到 2 个条目(点击次数)
addEventListener 的 once
选项是这样工作的:
once
A Boolean indicating that the listener should be invoked at most once after being added.
If true, the listener would be automatically removed when invoked.
所以如果 div 没有被点击,它的处理程序仍然停留在那里。当您再次点击播放时,您基本上会向 div 添加更多事件侦听器。为什么它随机被多次触发(在相同的 x/y 坐标)
要解决这个问题,只需删除重置中的事件侦听器
let doorLeft = document.getElementById("left");
let doorMiddle = document.getElementById("middle");
let doorRight = document.getElementById("right");
let resetButton = document.getElementById("reset");
let numberOfClicks = 0;
function incrementClicks() {
numberOfClicks++;
console.log('Number of clicks: ' + numberOfClicks)
}
/* -------------------------------------------------------------------------- */
/* handle click door only once */
/* -------------------------------------------------------------------------- */
const revealDoorColour = () => {
doorLeft.removeEventListener("click", incrementClicks);
doorMiddle.removeEventListener("click", incrementClicks);
doorRight.removeEventListener("click", incrementClicks);
//
doorLeft.addEventListener("click", incrementClicks, { once: true });
doorMiddle.addEventListener("click", incrementClicks, { once: true });
doorRight.addEventListener("click", incrementClicks, { once: true });
};
/* -------------------------------------------------------------------------- */
const reset = () => {
doorLeft.style.backgroundColor = "paleturquoise";
doorRight.style.backgroundColor = "paleturquoise";
doorMiddle.style.backgroundColor = "paleturquoise";
revealDoorColour();
resetButton.innerHTML = "Let's play";
};
resetButton.addEventListener("click", function() {
reset();
numberOfClicks = 0;
});
.container.main {
display: flex;
justify-content: space-around;
padding: 0 20%;
}
.door {
height: 500px;
width: 300px;
margin: 10px;
}
#left {
background-color: paleturquoise;
}
#middle {
background-color: paleturquoise;
}
#right {
background-color: paleturquoise;
}
.score {
text-align: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
<title>Door guesser</title>
<script src="./js/main.js" async></script>
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<div class="container main">
<div class="door" id="left">
</div>
<div class="door" id="middle">
</div>
<div class="door" id="right">
</div>
</div>
<div class="container score">
<div class="currentScoreGroup">
<div>Current score: </div>
<div id="currentScore">0</div>
</div>
<div class="bestScoreGroup">
<div>Best score: </div>
<div id="bestScore">0</div>
</div>
<button class="reset" id='reset'>Let's play </button>
</div>
</body>
</html>
let doorLeft = document.getElementById("left");
let doorMiddle = document.getElementById("middle");
let doorRight = document.getElementById("right");
let resetButton = document.getElementById("reset");
let numberOfClicks = 0;
function incrementClicks() {
numberOfClicks++;
console.log('Number of clicks: ' + numberOfClicks)
}
/* -------------------------------------------------------------------------- */
/* handle click door only once */
/* -------------------------------------------------------------------------- */
const revealDoorColour = () => {
doorLeft.addEventListener(
"click",
() => {
incrementClicks();
}, {
once: true,
}
);
doorMiddle.addEventListener(
"click",
() => {
incrementClicks();
}, {
once: true,
}
);
doorRight.addEventListener(
"click",
() => {
incrementClicks();
}, {
once: true,
}
);
};
/* -------------------------------------------------------------------------- */
const reset = () => {
doorLeft.style.backgroundColor = "paleturquoise";
doorRight.style.backgroundColor = "paleturquoise";
doorMiddle.style.backgroundColor = "paleturquoise";
revealDoorColour();
resetButton.innerHTML = "Let's play";
};
resetButton.addEventListener("click", function() {
reset();
numberOfClicks = 0;
});
.container.main {
display: flex;
justify-content: space-around;
padding: 0 20%;
}
.door {
height: 500px;
width: 300px;
margin: 10px;
}
#left {
background-color: paleturquoise;
}
#middle {
background-color: paleturquoise;
}
#right {
background-color: paleturquoise;
}
.score {
text-align: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
<title>Door guesser</title>
<script src="./js/main.js" async></script>
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<div class="container main">
<div class="door" id="left">
</div>
<div class="door" id="middle">
</div>
<div class="door" id="right">
</div>
</div>
<div class="container score">
<div class="currentScoreGroup">
<div>Current score: </div>
<div id="currentScore">0</div>
</div>
<div class="bestScoreGroup">
<div>Best score: </div>
<div id="bestScore">0</div>
</div>
<button class="reset" id='reset'>Let's play </button>
</div>
</body>
</html>
在
重现问题
- 点击开始玩吧
- 点击任意卡片
- 点击让我们再玩一次
- 点击另一张卡片
- 现在您应该在控制台中看到 2 个条目(点击次数)
addEventListener 的 once
选项是这样工作的:
once
A Boolean indicating that the listener should be invoked at most once after being added.
If true, the listener would be automatically removed when invoked.
所以如果 div 没有被点击,它的处理程序仍然停留在那里。当您再次点击播放时,您基本上会向 div 添加更多事件侦听器。为什么它随机被多次触发(在相同的 x/y 坐标)
要解决这个问题,只需删除重置中的事件侦听器
let doorLeft = document.getElementById("left");
let doorMiddle = document.getElementById("middle");
let doorRight = document.getElementById("right");
let resetButton = document.getElementById("reset");
let numberOfClicks = 0;
function incrementClicks() {
numberOfClicks++;
console.log('Number of clicks: ' + numberOfClicks)
}
/* -------------------------------------------------------------------------- */
/* handle click door only once */
/* -------------------------------------------------------------------------- */
const revealDoorColour = () => {
doorLeft.removeEventListener("click", incrementClicks);
doorMiddle.removeEventListener("click", incrementClicks);
doorRight.removeEventListener("click", incrementClicks);
//
doorLeft.addEventListener("click", incrementClicks, { once: true });
doorMiddle.addEventListener("click", incrementClicks, { once: true });
doorRight.addEventListener("click", incrementClicks, { once: true });
};
/* -------------------------------------------------------------------------- */
const reset = () => {
doorLeft.style.backgroundColor = "paleturquoise";
doorRight.style.backgroundColor = "paleturquoise";
doorMiddle.style.backgroundColor = "paleturquoise";
revealDoorColour();
resetButton.innerHTML = "Let's play";
};
resetButton.addEventListener("click", function() {
reset();
numberOfClicks = 0;
});
.container.main {
display: flex;
justify-content: space-around;
padding: 0 20%;
}
.door {
height: 500px;
width: 300px;
margin: 10px;
}
#left {
background-color: paleturquoise;
}
#middle {
background-color: paleturquoise;
}
#right {
background-color: paleturquoise;
}
.score {
text-align: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
<title>Door guesser</title>
<script src="./js/main.js" async></script>
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<div class="container main">
<div class="door" id="left">
</div>
<div class="door" id="middle">
</div>
<div class="door" id="right">
</div>
</div>
<div class="container score">
<div class="currentScoreGroup">
<div>Current score: </div>
<div id="currentScore">0</div>
</div>
<div class="bestScoreGroup">
<div>Best score: </div>
<div id="bestScore">0</div>
</div>
<button class="reset" id='reset'>Let's play </button>
</div>
</body>
</html>