My code only animates once after first 'game over' and 'reset' status. But after each next status change, animation(s) does/do not play again. I want to know if there is something wrong in my code, or there is a thing(s) to add/I omitted something? I provide you with my CSS/VanillaJS code below.
我的代码只在第一次‘游戏结束’和‘重置’状态后显示一次动画。但在每次下一次状态改变后,动画(S)不再播放/不再播放。我想知道是我的代码有问题,还是有什么东西(S)需要添加/我遗漏了什么?下面我给您提供我的css/VanillaJS代码。
VanillaJS =>
VanillaJS=>
const choices = document.querySelectorAll(".option");
const playerScoreElement = document.querySelector(".player-score");
const computerScoreElement = document.querySelector(".computer-score");
const chooseMove = document.querySelector(".choose-move");
const movesLeft = document.querySelector(".moves-left p");
const result = document.querySelector(".result");
const resetBtn = document.querySelector(".reset");
const modal = document.querySelector(".modal");
const optionsElement = document.querySelector(".options");
const mainHeaderElement = document.querySelector("h1");
let playerScore = 0;
let computerScore = 0;
let moves = 0;
const game = () => {
choices.forEach(choice => {
choice.addEventListener("click", () => {
moves++;
if (moves === 10) {
gameOver();
} else if(moves > 10) {
return;
}
// console.log(moves);
movesLeft.textContent = `Moves Left: ${10 - moves}`;
const playerChoice = choice.getAttribute(['data-choice']); // player choice
const computerChoices = ['rock', 'paper', 'scissors'];
const choiceIndex = Math.floor(Math.random() * 3);
const computerChoice = computerChoices[choiceIndex]; // computer choice
determineWinner(playerChoice, computerChoice);
})
})
resetBtn.addEventListener("click", resetGame);
};
const determineWinner = (playerChoice, computerChoice) => {
if (playerChoice === "rock" && computerChoice === "scissors" ||
playerChoice === "scissors" && computerChoice === "paper" ||
playerChoice === "paper" && computerChoice === "rock"
) {
playerScore++;
playerScoreElement.textContent = playerScore;
result.textContent = "You win a point!";
} else if (playerChoice === computerChoice) {
result.textContent = "A Draw!";
} else {
computerScore++;
computerScoreElement.textContent = computerScore;
result.textContent = "Computer wins a point!";
}
}
const gameOver = () => {
const finalResult = playerScore === computerScore ? "Game Over! It's a draw!" :
playerScore > computerScore ? "Game Over! You have won!" :
"Game Over! Computer has won!"
chooseMove.textContent = finalResult;
chooseMove.style.marginTop = "1em";
chooseMove.style.transition = "all 500ms ease-in-out";
chooseMove.style.transform = "scale(1.02)";
chooseMove.style.color = "red";
chooseMove.style.fontSize = "2rem";
result.textContent = "";
resetBtn.style.display = "block";
resetBtn.textContent = 'Reset Game';
mainHeaderElement.style.opacity = "0";
modal.setAttribute("open", "");
movesLeft.style.display = "none";
optionsElement.style.display = "none";
result.style.display = "none";
return;
}
const resetGame = () => {
moves = 0;
playerScore = 0;
computerScore = 0;
playerScoreElement.textContent = playerScore;
computerScoreElement.textContent = computerScore;
chooseMove.textContent = "Choose your move!";
movesLeft.style.display = "block";
movesLeft.textContent = `Moves Left: 10`;
result.textContent = "";
resetBtn.style.display = "none";
mainHeaderElement.style.opacity = "1";
modal.setAttribute("close", "");
optionsElement.style.display = "flex";
result.style.display = "flex";
}
game();
CSS =>
Css=>
.modal {
position: fixed;
background: rgb(255, 252, 252);
box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
color: white;
top: 20%;
left: 50%;
transform: translateX(-50%);
text-align: center;
font-size: 2rem;
padding: 0.5em;
width: 30em;
border-radius: 2px;
opacity: 0;
pointer-events: none;
z-index: 1;
}
.modal p {
color: red;
}
.modal[open] {
animation: modal-fade-in 500ms;
animation-fill-mode: forwards;
}
.modal[close] {
animation: modal-fade-out 500ms;
animation-fill-mode: forwards;
}
/* MODAL WINDOW ANIMATIONS */
@keyframes modal-fade-in {
0% {
display: none;
opacity: 0;
}
1% {
display: block;
}
100% {
display: block;
opacity: 1;
}
}
@keyframes modal-fade-out {
0% {
display: block;
opacity: 1;
}
99% {
display: block;
}
100% {
display: none;
opacity: 0;
}
}
更多回答
Thank you for your suggestions, they have been most helpful! I decided to use solution which includes removing corresponding attribute in each function before adding another one.
谢谢你的建议,它们对我们很有帮助!我决定使用解决方案,其中包括在添加另一个函数之前删除每个函数中的相应属性。
优秀答案推荐
When you set the attribute "open" and then set the attribute "close", the resulting modal has both "open" and "close" attributes set so it is essentially getting confused because both are applied after you close it for the first time.
当您将属性设置为“打开”,然后将属性设置为“关闭”时,生成的模式同时设置了“打开”和“关闭”属性,因此本质上是混淆的,因为这两个属性都是在您第一次关闭它之后应用的。
there are a handful of ways to handle this, you can make separate open and close classes and toggle them on and off like the below example, you could set the attribute like this setAttribute('data-modal','open') and setAttribute('data-modal','close') and adjust the selectors accordingly, this way when you set the attribute its actually changing it from open to closed not setting separate attributes, or you could toggle a single class on and off and not use a keyframe animation but instead use a css transition (display isn't a animatable property, so it would only transition opacity, and since you are preventing click events it should be fine when hidden)
有几种方法可以处理这个问题,你可以像下面的例子一样设置单独的开放类和关闭类并打开和关闭它们,你可以像这样设置属性setAttribute(‘data-modal’,‘Open’)和setAttribute(‘data-modal’,‘Close’),并相应地调整选择器,这样当你设置属性时,它实际上将它从打开更改为关闭,而不是设置单独的属性,或者你可以打开和关闭单个类,而不使用关键帧动画,而使用CSS过渡(Display不是一个可动画的属性,所以它只会转换不透明度,由于您正在阻止点击事件,因此隐藏时应该没有问题)
Also check out the html dialog element. It probably wont help much since you already made your own and it doesn't animate by default, but it can save you some time if you figure it out. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog
还可以查看html对话框元素。它可能不会有太多帮助,因为你已经做了自己的,它不是默认的动画,但它可以节省你一些时间,如果你弄清楚了。Https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog
document.querySelector('#open').onclick = function() {
document.querySelector('#workingModal').classList.remove('close');
document.querySelector('#workingModal').classList.add('open');
document.querySelector('#notWorking').setAttribute('open','');
}
document.querySelector('#close').onclick = function() {
document.querySelector('#workingModal').classList.remove('open');
document.querySelector('#workingModal').classList.add('close');
document.querySelector('#notWorking').setAttribute('close','');
}
.modal {
position: fixed;
background: rgb(255, 252, 252);
box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
color: blue;
top: 20%;
left: 50%;
transform: translateX(-50%);
text-align: center;
font-size: 2rem;
padding: 0.5em;
width: 30em;
border-radius: 2px;
opacity: 0;
pointer-events: none;
z-index: 1;
}
.modal[open] {
animation: modal-fade-in 500ms;
animation-fill-mode: forwards;
}
.modal[close] {
animation: modal-fade-out 500ms;
animation-fill-mode: forwards;
}
.modal.open {
animation: modal-fade-in 500ms;
animation-fill-mode: forwards;
}
.modal.close {
animation: modal-fade-out 500ms;
animation-fill-mode: forwards;
}
/* MODAL WINDOW ANIMATIONS */
@keyframes modal-fade-in {
0% {
display: none;
opacity: 0;
}
1% {
display: block;
}
100% {
display: block;
opacity: 1;
}
}
@keyframes modal-fade-out {
0% {
display: block;
opacity: 1;
}
99% {
display: block;
}
100% {
display: none;
opacity: 0;
}
}
<button id="open">open</button>
<button id="close">close</button>
<div class="modal" id="workingModal">
I animate
</div>
<div class="modal" id="notWorking" style="top:40%;">
I don't animate
</div>
更多回答
我是一名优秀的程序员,十分优秀!