首页 > 解决方案 > 在第一个事件侦听器单击执行后退出 for 循环

问题描述

我正在开发井字游戏,我希望用户能够单击板上的九个框之一。我实现了一个for loop在每个 div 上运行,允许用户单击每个 div。

在他们选择了他们的盒子后,计算机将开始移动。

一旦用户选择了他们的框,我该如何停止循环?先感谢您

//initial variables
let box = document.querySelectorAll(".box");
let letter = document.querySelector('.letter');
let turn = 0;
//START GAME
let userXorO = function() { //function to determine whose x and o

  let X = 1;
  let O = 2;
  
  let random = Math.floor(Math.random() * 2) + 1; //randomizes between x and o
  
      if (random == X) { 
        return 'X'
      }

      if (random == O) {
        return 'O'
      }
    
    return random; //returns random number to function
  }

//PLAYER ONE INITIAL TURN
function turn_one() {


  for (let i = 0; i < box.length; i++) {
    if (turn === 0) {
      box[i].addEventListener("click", function(e) {
        box[i].textContent = userXorO(); //draws first user X or O 
        turn ++;
      });
      
    }
  }
}

turn_one();
.game-board {
  width: 600px;
  height: 600px;
  margin: 0 auto;
  background-color: #34495e;
  color: #fff;
  border: 6px solid #2c3e50;
  border-radius: 10px;
  display: grid;
  grid-template: repeat(3, 1fr) / repeat(3, 1fr);
}

.box {
  border: 6px solid #2c3e50;
  border-radius: 2px;
  font-family: Helvetica;
  font-weight: bold;
  font-size: 4em;
  display: flex;
  justify-content: center;
  align-items: center;
}

.player_one {
  background-color: red;
}
<div class="game-board">
  <div id="1" class="box"><span id="1" class="letter"></span></div>
  <div id="2" class="box"><span id="2" class="letter"></span></div>
  <div class="box"><span id="3" class="letter"></span></div>
  <div class="box"><span id="" class="letter"></span></div>
  <div class="box"><span id="" class="letter"></span></div>
  <div class="box"><span id="" class="letter"></span></div>
  <div class="box"><span id="" class="letter"></span></div>
  <div class="box"><span id="" class="letter"></span></div>
  <div class="box"><span id="" class="letter"></span></div>
</div>

标签: javascripthtmlcss

解决方案


与其在人类第一次选择一个框后添加许多您可能会尝试删除的侦听器,不如在整个容器中仅添加一个侦听器(这称为事件委托),您可能会发现逻辑更容易遵循,并且使用类似的变量检查点击当前是否有效isHumanTurn。(当然,如果计算机立即轮到它,则无需isHumanTurn检查。)

另请注意,同一文档中的重复 ID 是无效的 HTML - 最好将其删除。(要检查在其容器中单击的索引div,您可以indexOf在 s 的数组上使用div

另一个问题是你应该在游戏开始时构建 randomXO once,而不是在每次点击时,否则它会不一致。

例如:

const humanTile = ['X', 'O'][Math.floor(Math.random() * 2)];

let isHumanTurn = true;
function handleClick({ target }) {
  if (!target.matches('.box')) return;
  if (!isHumanTurn) return console.log('It is not your turn!');
  target.textContent = humanTile; //draws first user X or O
  isHumanTurn = false;
  console.log('insert function call for computer to take its turn...');
}
document.querySelector('.game-board').addEventListener('click', handleClick);
.game-board {
  width: 600px;
  height: 600px;
  margin: 0 auto;
  background-color: #34495e;
  color: #fff;
  border: 6px solid #2c3e50;
  border-radius: 10px;
  display: grid;
  grid-template: repeat(3, 1fr) / repeat(3, 1fr);
}

.box {
  border: 6px solid #2c3e50;
  border-radius: 2px;
  font-family: Helvetica;
  font-weight: bold;
  font-size: 4em;
  display: flex;
  justify-content: center;
  align-items: center;
}

.player_one {
  background-color: red;
}
<div class="game-board">
  <div class="box"><span class="letter"></span></div>
  <div class="box"><span class="letter"></span></div>
  <div class="box"><span class="letter"></span></div>
  <div class="box"><span class="letter"></span></div>
  <div class="box"><span class="letter"></span></div>
  <div class="box"><span class="letter"></span></div>
  <div class="box"><span class="letter"></span></div>
  <div class="box"><span class="letter"></span></div>
  <div class="box"><span class="letter"></span></div>
</div>


推荐阅读