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

问题描述 投票:0回答:1

第一次发帖。 我有一些代码不能正常工作。 我正在创建一个Simon Says游戏,我试图使用jQuery中的setTimeout函数来实现在一个项目数组中添加和删除一个类。 当我在while循环外使用addClass和removeClass方法时,它会改变类,然后把它改回来。 然而,当我把它放在一个while循环里面(所以我可以循环之前的Simon Says按钮序列),这个类被添加到元素,但在setTimeout函数的规定时间后,并没有改变回来。

下面是代码。

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>

注释的部分是实际工作的代码,它改变了元素,然后在500ms后将其变回。 在while循环里面,console.log消息确实显示了正确的信息。

javascript jquery while-loop settimeout
1个回答
0
投票

到底发生了什么?

事实上,问题在于 while 循环不等 setTimeout. 所以它将增加 ticker 之前 setTimeout 处理程序被执行。由于你的 gamePattern 是一个只有一个元素的数组,当 ticker 获得增量的结果 gamePattern[ticker] 将是 undefined 所以它不会在你的DOM中找到这样一个元素。

如何解决这个问题?

为了解决这个问题,你需要为每个元素设置不同的执行时间延迟,然后我们需要使用一个简单的方法来解决这个问题。closure 以保持当前的 ticker 然后传给 setTimeout 正确。在你的特殊情况下,函数需要被初始执行,所以我们需要使用一个 匿名的 function.

所以你的最终代码应该是这样的。

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>
© www.soinside.com 2019 - 2024. All rights reserved.