简体   繁体   中英

Exit out of for loop after first event listener click executes

I'm working on a tic tac toe board and I would like the user to be able to click on one of the nine boxes on the board. I implemented a for loop to run over each div, allowing each one to be clicked by the user.

After they select their box, the computer will then make its move.

How can I stop the loop, once the user selects their box ? Thank you in advance

 //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> 

Rather than adding lots of listeners that you might try to remove after the human selects a box the first time, you might find the logic easier to follow if you added only one listener, to the entire container (this is called event delegation ), and check to see if the click is currently valid using a variable like isHumanTurn . (Of course, if the computer takes its turn instantly , there's no need for a isHumanTurn check.)

Also note that duplicate IDs in the same document is invalid HTML - best to remove those. (To check the index of a clicked div in its container, you can use indexOf on an array of the div s)

Another issue is you should construct the random X or O once , at the beginning of the game, not on every click, else it won't be consistent.

For example:

 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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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