Estoy tratando de construir un tablero de ajedrez muy básico (sin reglas incrustadas) como un desafío de aprendizaje. Básicamente, mi tablero está hecho de 64 divs, donde cada div tiene una clase .square . Tengo dos funciones: una para agregar la clase .active al cuadrado en el que se hizo clic y otra función para mover la pieza con la clase .active al nuevo cuadrado. Intenté poner los dos eventListeners diferentes para llamar a las diferentes funciones en una declaración IF ELSE, pero mi condición no funciona porque el querySelector no verifica en tiempo real si hay algún div con la clase .active en ese dado momento.
Mi código se ve así:
let squares = document.querySelectorAll(`.square`); let activeSquares = document.querySelectorAll(`.active`); // This condition needs to check if there's any square with the class .active in REAL TIME if (activeSquares.length > 0) { squares.forEach(square => { square.addEventListener(`click`, movePiece); function movePiece() { let pieceToMove = document.querySelector(`.active`).textContent; square.textContent = pieceToMove; } }); } else { squares.forEach(square => { square.addEventListener(`click`, selectPiece); function selectPiece() { square.className = `active square`; } }); }¿Cómo hago para que verifique la clase en tiempo real? ¿O mi enfoque es completamente incorrecto? Tenga piedad, solo he estado aprendiendo estas cosas durante un par de meses, si me falta algún conocimiento básico, indíquelo para que pueda buscarlo.
¡Gracias!
Su código simple se verá así, puedes desarrollarlo:
const squares = document.getElementsByClassName('square') Array.from(squares).forEach(ele => { ele.addEventListener('click', function () { if(this.classList.contains('active')) { this.classList.remove("active") } else { currentActive = document.getElementsByClassName('active')[0] if (currentActive) { let thisHtml = this.innerHTML this.innerHTML = currentActive.innerHTML currentActive.innerHTML = thisHtml currentActive.classList.remove("active") } else { this.classList.add("active") } } }) }) #container { height: 169px; width: 169px; } .square { height: 40px; width: 40px; background-color: #ccc; float:left; left: 0; border: solid 1px; } .active { background-color: red; } <div id="container"> <div class='square'>1</div> <div class='square'></div> <div class='square'></div> <div class='square'></div> <div class='square'></div> <div class='square'></div> <div class='square'></div> <div class='square'></div> <div class='square'></div> <div class='square'></div> <div class='square'></div> <div class='square'></div> <div class='square'></div> <div class='square'></div> <div class='square'></div> <div class='square'></div> </div>En el controlador de eventos (una función que se llama cuando se activa un evento registrado) usamos la propiedad del objeto de evento Event.target que siempre apunta a la etiqueta con la que interactuó el usuario. Lea los siguientes artículos para obtener más detalles:
Los detalles se comentan en el ejemplo.
// Reference <table> const board = document.querySelector('.board'); // This function goes beyond the scope of the question const buildTable = table => { const file = ['a', 'b', 'c', 'd', 'e', 'f', 'h', 'g']; const rank = [8, 7, 6, 5, 4, 3, 2, 1]; let matrix = []; for (let r = 0; r < 8; r++) { let row = table.insertRow(); matrix.push([]); for (let c = 0; c < 8; c++) { let col = row.insertCell(); col.dataset.pos=`${file[c]+rank[r]}`; matrix[r].push(`${file[c]+rank[r]}`); } } return matrix; }; const matrix = buildTable(board); //console.log(matrix); // Bind the 'click' event to <table> board.onclick = activeSQ; function activeSQ(e) { // Reference the tag user clicked const clk = e.target; /* If the user clicked a <td>... ...remove .active from the <td> that was .active previously... ...then add .active to the <td> the user clicked... ...log the algebraic notation of the clicked square */ if (clk.matches('td')) { const prev = this.querySelector('td.active'); if (prev) { prev.classList.remove('active'); } clk.classList.add('active'); console.log(clk.dataset.pos); } } *, *::before, *::after { box-sizing: border-box; } :root { font: 1vw/1 'Segoe UI'; } html, body { width: 100%; height: 100%; } body { overflow: hidden; } table { table-layout: fixed; border-collapse: collapse; width: 40%; margin: 2.5% auto; border: 0.5px solid lightgrey; } td { width: 12.5%; height: 5rem; border: 0.5px solid lightgrey; } tr:nth-of-type(odd) td:nth-of-type(even) { background: black; } tr:nth-of-type(even) td:nth-of-type(odd) { background: black; } .pos { display: block; } .white, .black { display: inline-flex; justify-content: center; align-items: center; width: 90%; height: 90%; } td.active { outline: 3px inset gold; } .as-console-row::after { width: 0; font-size: 0; } .as-console-row-code { width: 100%; word-break: break-word; } .as-console-wrapper { max-height: 25% !important; } <table class='board'></table>