I want to attach event listeners to every cell in each of the two grids so that when I click on my opponent's grid (and it's my turn) I can attack with func() which also flips turn. Then when my opponent clicks on my grid (and it's their turn) they attack with func() and switch turn back to me. The issue with this code is the event listeners seem to only attach once per grid. So I can attack once and my opponent can attack me once and then I can't attack again. How could I solve this?
const cells = document.querySelectorAll("#enemyGrid .cell");
for (let i = 0; i < cells.length; i++) {
cells[i].addEventListener("click", () => {
if (turn === 0) {
//do stuff
func(); //sets turn=1
}
});
}
const cellsMe = document.querySelectorAll("#meGrid .cell");
for (let i = 0; i < cellsMe.length; i++) {
cellsMe[i].addEventListener("click", () => {
if (turn === 1) {
//do stuff
func(); //sets turn =0
}
});
}
This is a very simple demo trying to accomplish what you are expecting.
I kept the structure of your dom and crafted a js function that will populate the .grid elements with a given number of cells that will be styled in a grid layout.
To those cells will be later added a click event listener with no discrimination of player, that will check the user having the latest move and will prevent the same player to pick a cell before the other player made its choice.
Everytime a player picks a cell, the turn counter increments, the background of the picked cell turns to red and the event gets printed on console
//build the grids
const grids = document.querySelectorAll('.grid');
grids.forEach(grid => populateGrid(grid, 10));
//populates the given grid in target with size*size cells
function populateGrid(target, size) {
for (let i = 0; i < size * size; i++) {
const cell = document.createElement('div');
cell.classList.add('cell');
target.appendChild(cell);
}
}
//function called each time the click event occurs on cells
let turn = 0;
let latestMoveBy = '';
function playerMove(player, cell){
if(latestMoveBy == player)
return;
turn++;
cell.classList.add('picked');
latestMoveBy = player;
console.log(`Player: ${player} picked a cell at turn: ${turn}`);
}
//pick all the .cell elements inside a .grid
document.querySelectorAll(".grid .cell")
//and for each one of them attach a click event handler
.forEach( cell => {
cell.addEventListener("click", (event) => {
const clickedCell = event.target;
const player = clickedCell.parentElement.dataset.player;
playerMove(player, clickedCell);
});
});
.grid>.cell {
background: darkgray;
cursor: pointer;
width: 20px;
height: 20px;
}
.grid {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(10, auto);
grid-template-rows: auto;
grid-auto-flow: row;
width: fit-content;
box-sizing: border-box;
}
.picked {
background: red !important;
}
<div id="enemyGrid" class="grid" data-player="player1">
</div>
<hr>
<div id="meGrid" class="grid" data-player="player2">
</div>