简体   繁体   English

addClass 和 removeClass jQuery 问题(SetTimeout 在循环内不起作用)

[英]addClass and removeClass jQuery issues (SetTimeout does not work inside loop)

First time posting.第一次发帖。 I am having trouble getting some code to work.我无法让一些代码工作。 I am creating a Simon Says game and I am trying to achieve adding and removing a class to an array of items using the setTimeout function in jQuery.我正在创建一个 Simon Says 游戏,我正在尝试使用 jQuery 中的 setTimeout function 将 class 添加和删除到项目数组中。 When I use the addClass and removeClass methods outside of a while loop by themselves, it will change the class and then change it back.当我自己在 while 循环之外使用 addClass 和 removeClass 方法时,它会更改 class 然后再改回来。 However, when I put it inside of a while loop (so I can loop through the previous Simon Says button sequence) the class is added to the element, but then does not change back after the allotted time on the setTimeout function.然而,当我把它放在一个while循环中(这样我可以循环之前的Simon Says按钮序列)时,class被添加到元素中,但在setTimeout function的分配时间之后不会变回来。

Here is the code:这是代码:

 var buttonColors = ["red", "blue", "green", "yellow"]; var gamePattern = []; function nextSequence() { var randomNumber = Math.floor(Math.random() * 4); gamePattern.push(randomNumber); // $("#" + buttonColors[randomNumber]).addClass("pressed"); // setTimeout(function() { // $("#" + buttonColors[randomNumber]).removeClass("pressed"); // }, 500); var ticker = 0; while (ticker < gamePattern.length) { console.log("#" + buttonColors[gamePattern[ticker]]); $("#" + buttonColors[gamePattern[ticker]]).addClass("pressed"); setTimeout(function() { $("#" + buttonColors[gamePattern[ticker]]).removeClass("pressed"); }, 500); ticker += 1; } }
 <link href="https://fonts.googleapis.com/css?family=Press+Start+2P" rel="stylesheet"> <h1 id="level-title">Press A Key to Start</h1> <div class="container"> <div lass="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="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

The commented portion is the code that actually works to change the element and then change it back after 500ms.注释部分是实际用于更改元素并在 500 毫秒后将其更改回来的代码。 Inside the while loop, the console.log message does display the correct information.在 while 循环中,console.log 消息确实显示了正确的信息。

What's happening?发生了什么?

Actually the problem is while loop will not wait for setTimeout .实际上问题是while循环不会等待setTimeout So it will increment the ticker before setTimeout handler gets executed.所以它会在setTimeout处理程序被执行之前增加ticker Since your gamePattern is an array of one element when ticker gets increment the result of gamePattern[ticker] will be undefined so it won't find such an element in your DOM.由于您的gamePattern是一个元素的数组,当ticker递增时, gamePattern[ticker]的结果将是undefined的,因此它不会在您的 DOM 中找到这样的元素。

How to fix this?如何解决这个问题?

In order to fix this, You need to set a different time delay for each to execute, then we need to use a simple closure to hold the current value of ticker and then pass it to the setTimeout correctly.为了解决这个问题,您需要为每个执行设置不同的时间延迟,然后我们需要使用一个简单的closure来保存ticker的当前值,然后将其正确传递给setTimeout In your particular case function needs to be executed initially so we need to use an anonymous function .在您的特定情况下,首先需要执行 function ,因此我们需要使用匿名function

So your final code should be something like this:所以你的最终代码应该是这样的:

 var buttonColors = ["red", "blue", "green", "yellow"]; var gamePattern = []; function nextSequence() { var randomNumber = Math.floor(Math.random() * 4); gamePattern.push(randomNumber); // $("#" + buttonColors[randomNumber]).addClass("pressed"); // setTimeout(function() { // $("#" + buttonColors[randomNumber]).removeClass("pressed"); // }, 500); var ticker = 0; while (ticker < gamePattern.length) { $("#" + buttonColors[gamePattern[ticker]]).addClass("pressed"); console.log("#" + buttonColors[gamePattern[ticker]]); (function(ticker) { setTimeout(function() { $("#" + buttonColors[gamePattern[ticker]]).removeClass("pressed"); console.log("#" + buttonColors[gamePattern[ticker]]); }, 500 * ticker) })(ticker++) } } nextSequence();
 <.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 lass="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> <.-- jQuery --> <script src="https.//ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <!-- Javascript --> <script src="game.js" charset="utf-8"></script> </body> </html>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM