HTML 元素上的连续动画
伙计们。我试图通过按钮上的 css 类创建一组连续的“动画”,但我不断遇到一个问题,即我的所有按钮同时收到效果,而不是一个接一个。
函数 playAllSequence 应按照数组中存在的顺序依次突出显示每个按钮。
我已经尝试将 setTimeOut 函数放入闭包中,并尝试将声明更改为 let 而不是 var。
我缺少什么?
提前致谢
// Get number of buttons on the document
var numberOfButtons = document.querySelectorAll(".btn").length;
var collectionButtonsClicked = [];
var collectionOfRandomColors = [];
var buttonsColors = ["blue", "green", "red", "yellow"];
var gameTitle = document.querySelector("#level-title");
// detecting clicks on the buttons
for ( let i = 0; i < numberOfButtons; i++) {
document.querySelectorAll(".btn")[i].addEventListener("click", function () {
collectionButtonsClicked.push(this.id);
// call click animation function
clickAnimation ();
// Only checks when arrays have the same length so the user have to click all the sequence again
if (collectionButtonsClicked.length === collectionOfRandomColors.length) {
checkClick();
}
})};
// detecting button press to start the game
document.addEventListener("keydown", function (event) {
if (event.key === "a") {
gameTitle.innerHTML = "Game Started";
generateRandomColor();
playAllSequence();
}
});
// check if the click is correct
function checkClick () {
// if correct - Generate new color, disable buttons and play the sequence on all buttons
let arrayRandomStringfied = JSON.stringify(collectionOfRandomColors);
let arrayClickedStringfied = JSON.stringify(collectionButtonsClicked);
if (arrayRandomStringfied === arrayClickedStringfied) {
generateRandomColor();
playAllSequence();
console.log("acertou!")
// erasing click array so the player has to click all the color again
collectionButtonsClicked = [];
} else {
//call fail animation function
failAnimation();
// function to reset the arrays and the title
restartGame();
console.log("errou!")
}
}
//Generate random color and return array - User will have to follow this colors
function generateRandomColor () {
let randomIndex = Math.floor(Math.random() * 4);
collectionOfRandomColors.push(buttonsColors[randomIndex]);
return collectionOfRandomColors;
}
function playAllSequence () {
// disabling all buttons
for ( let i = 0; i < numberOfButtons; i++) {
document.querySelectorAll(".btn")[i].disabled = true;
}
for ( let i = 0; i < collectionOfRandomColors.length; i++ ) {
doSetTimeOut(i);
}
// Enabling all buttons again
for ( let i = 0; i < numberOfButtons; i++) {
document.querySelectorAll(".btn")[i].disabled = false;
}
}
function doSetTimeOut (i) {
let activeButton = document.querySelector("." + collectionOfRandomColors[i]);
// Add pressed effect
activeButton.classList.add("pressed");
// Remove pressed effect after 1 second
setTimeout(function() {
activeButton.classList.remove("pressed")
}, 1000);
}
function clickAnimation () {
}
function failAnimation () {
}
function restartGame () {
collectionOfRandomColors = [];
collectionButtonsClicked = [];
gameTitle.innerHTML = "Press A key to Start";
}
body {
text-align: center;
background-color: #011F3F;
}
#level-title {
font-family: 'Press Start 2P', cursive;
font-size: 3rem;
margin: 5%;
color: #FEF2BF;
}
.container {
display: block;
width: 50%;
margin: auto;
}
.btn {
margin: 25px;
display: inline-block;
height: 200px;
width: 200px;
border: 10px solid black;
border-radius: 20%;
}
.game-over {
background-color: red;
opacity: 0.8;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.blue {
background-color: blue;
}
.yellow {
background-color: yellow;
}
.pressed {
box-shadow: 0 0 20px white;
background-color: grey;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Simon</title>
<link rel="stylesheet" href="styles.css">
<link href="https://fonts.googleapis.com/css?family=Press+Start+2P" rel="stylesheet">
</head>
<body>
<h1 id="level-title">Press A Key to Start</h1>
<div class="container">
<div class="row">
<div type="button" id="green" class="btn green">
</div>
<div type="button" id="red" class="btn red">
</div>
</div>
<div class="row">
<div type="button" id="yellow" class="btn yellow">
</div>
<div type="button" id="blue" class="btn blue">
</div>
</div>
</div>
<script src="index.js" charset="utf-8"></script>
</body>
</html>
guys. I'm trying to create a group of sequential "animations" through css classes on my buttons, but i keep getting a problem where all my buttons receive the effect on the same time and not one after another.
The function playAllSequence should hightlight each button one after another following the sequence present in an array.
I've already tried to put the setTimeOut function inside a closure and tried changed my declaration to let instead of var.
What am i missing?
Thanks in advance
// Get number of buttons on the document
var numberOfButtons = document.querySelectorAll(".btn").length;
var collectionButtonsClicked = [];
var collectionOfRandomColors = [];
var buttonsColors = ["blue", "green", "red", "yellow"];
var gameTitle = document.querySelector("#level-title");
// detecting clicks on the buttons
for ( let i = 0; i < numberOfButtons; i++) {
document.querySelectorAll(".btn")[i].addEventListener("click", function () {
collectionButtonsClicked.push(this.id);
// call click animation function
clickAnimation ();
// Only checks when arrays have the same length so the user have to click all the sequence again
if (collectionButtonsClicked.length === collectionOfRandomColors.length) {
checkClick();
}
})};
// detecting button press to start the game
document.addEventListener("keydown", function (event) {
if (event.key === "a") {
gameTitle.innerHTML = "Game Started";
generateRandomColor();
playAllSequence();
}
});
// check if the click is correct
function checkClick () {
// if correct - Generate new color, disable buttons and play the sequence on all buttons
let arrayRandomStringfied = JSON.stringify(collectionOfRandomColors);
let arrayClickedStringfied = JSON.stringify(collectionButtonsClicked);
if (arrayRandomStringfied === arrayClickedStringfied) {
generateRandomColor();
playAllSequence();
console.log("acertou!")
// erasing click array so the player has to click all the color again
collectionButtonsClicked = [];
} else {
//call fail animation function
failAnimation();
// function to reset the arrays and the title
restartGame();
console.log("errou!")
}
}
//Generate random color and return array - User will have to follow this colors
function generateRandomColor () {
let randomIndex = Math.floor(Math.random() * 4);
collectionOfRandomColors.push(buttonsColors[randomIndex]);
return collectionOfRandomColors;
}
function playAllSequence () {
// disabling all buttons
for ( let i = 0; i < numberOfButtons; i++) {
document.querySelectorAll(".btn")[i].disabled = true;
}
for ( let i = 0; i < collectionOfRandomColors.length; i++ ) {
doSetTimeOut(i);
}
// Enabling all buttons again
for ( let i = 0; i < numberOfButtons; i++) {
document.querySelectorAll(".btn")[i].disabled = false;
}
}
function doSetTimeOut (i) {
let activeButton = document.querySelector("." + collectionOfRandomColors[i]);
// Add pressed effect
activeButton.classList.add("pressed");
// Remove pressed effect after 1 second
setTimeout(function() {
activeButton.classList.remove("pressed")
}, 1000);
}
function clickAnimation () {
}
function failAnimation () {
}
function restartGame () {
collectionOfRandomColors = [];
collectionButtonsClicked = [];
gameTitle.innerHTML = "Press A key to Start";
}
body {
text-align: center;
background-color: #011F3F;
}
#level-title {
font-family: 'Press Start 2P', cursive;
font-size: 3rem;
margin: 5%;
color: #FEF2BF;
}
.container {
display: block;
width: 50%;
margin: auto;
}
.btn {
margin: 25px;
display: inline-block;
height: 200px;
width: 200px;
border: 10px solid black;
border-radius: 20%;
}
.game-over {
background-color: red;
opacity: 0.8;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.blue {
background-color: blue;
}
.yellow {
background-color: yellow;
}
.pressed {
box-shadow: 0 0 20px white;
background-color: grey;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Simon</title>
<link rel="stylesheet" href="styles.css">
<link href="https://fonts.googleapis.com/css?family=Press+Start+2P" rel="stylesheet">
</head>
<body>
<h1 id="level-title">Press A Key to Start</h1>
<div class="container">
<div class="row">
<div type="button" id="green" class="btn green">
</div>
<div type="button" id="red" class="btn red">
</div>
</div>
<div class="row">
<div type="button" id="yellow" class="btn yellow">
</div>
<div type="button" id="blue" class="btn blue">
</div>
</div>
</div>
<script src="index.js" charset="utf-8"></script>
</body>
</html>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,我什至没有看到您的示例代码来为第一个按钮设置动画。
如果您需要在视觉上“一对一”地发生独立的单独事件,您可以使用
i*1000
作为setTimeout
第二个参数。如果没有,我相信这里的代码正在做一些接近您想要实现的事情。定义一个函数,为索引所采用的元素设置所需的道具(本例中为 box-shadow),并为将删除道具并使用下一个索引再次调用第一个函数的函数设置超时:
Well, I don't see your sample code to animate even the first button.
If you need independent separate events to happen '1 by 1' visually, you might use a
i*1000
as asetTimeout
second argument.If not, here's the code doing something close to what you want to achieve, i believe. Define a function that sets the props you need (box-shadow in this example) for an element taken by index, and sets timeout for a function that will remove the props and call the first function again with the next index: