Construir una interfaz de juego donde los botones de ataque se generan de forma dinámica es un paso fundamental para que cualquier Mokepon seleccionado muestre sus propios movimientos. Aquí se explica cómo crear la función mostrar ataques, inyectar elementos en el DOM y resolver los errores más comunes al reubicar variables y eventos.
¿Cómo se construye la función mostrar ataques?
El punto de partida es la función mostrarAtaques, que recibe como parámetro el arreglo de ataques del personaje seleccionado. Dentro de ella se utiliza el método forEach [03:07] para recorrer cada elemento del arreglo. Por cada ataque se construye un fragmento de HTML que representa un botón, aprovechando dos propiedades del objeto: ataque.id y ataque.nombre.
- Se declara una variable (
ataquesMokepon) que acumula la estructura HTML de todos los botones.
- Cada iteración concatena un nuevo botón con el id y el nombre correspondiente.
- Al terminar el ciclo, se inyecta todo el contenido dentro del contenedor usando
innerHTML con el operador += [04:35].
El contenedor se identifica en el HTML con un id llamado contenedor-ataques, y se captura con document.getElementById [02:18]. Como ese elemento ya existe en el documento desde el inicio, se puede declarar como const, ya que la referencia al nodo no cambia.
¿Por qué se eliminan los botones estáticos del HTML?
Antes de probar la función, los botones que estaban escritos directamente en el archivo HTML se borran [05:05]. Estos botones fijos no representan los ataques reales del personaje elegido, así que mantenerlos generaría inconsistencias. A partir de este punto, todo botón de ataque se crea exclusivamente desde JavaScript.
¿Cómo se resuelve el error de elementos nulos?
Al refrescar el navegador aparece un error de tipo null [05:22]. Esto ocurre porque, en la parte superior del archivo JavaScript, se intentan capturar elementos del DOM que todavía no existen: los botones recién se inyectan más abajo, dentro de mostrarAtaques.
La solución es mover las declaraciones de variables (botonFuego, botonAgua, botonTierra) desde la zona superior del script hasta un punto posterior a la inyección de los botones [06:15].
- Las variables pasan de ser
const a let, porque su asignación ocurre en un momento distinto al de su declaración.
- Se reubican justo después de la línea donde
innerHTML ya insertó los botones en el DOM.
- De esta forma,
document.getElementById encuentra los elementos correctamente.
¿Por qué también hay que mover los eventos de clic?
No basta con reubicar las variables. Las líneas que agregan el addEventListener de clic a cada botón también deben colocarse después de que las variables ya apunten a un elemento real del DOM [08:00]. Si el evento se registra antes de que el botón exista, simplemente no funciona.
- Se cortan las líneas de
addEventListener de la parte superior.
- Se pegan debajo de la asignación de variables, donde los botones ya son nodos válidos.
- Cada evento dispara la función correspondiente: seleccionar fuego, agua o tierra.
¿Qué problema queda pendiente con los botones repetidos?
Al seleccionar un personaje que tiene ataques repetidos (por ejemplo, dos botones de agua), solo el primer botón con ese id responde al clic [10:40]. Los demás botones con el mismo identificador no ejecutan ninguna acción. Esto sucede porque getElementById devuelve únicamente la primera coincidencia; los duplicados quedan sin evento.
Este comportamiento revela una limitación importante: cuando se generan múltiples botones con el mismo id, el enlace entre variable y elemento solo funciona para el primero. La solución requiere asignar el evento de clic a cada botón individual durante la iteración del forEach, algo que se aborda en la siguiente sesión.
- El juego ya funciona correctamente con el primer botón de cada tipo.
- Los ataques duplicados necesitan una estrategia diferente para registrar eventos.
- El patrón de inyectar HTML y luego capturar elementos es útil, pero exige cuidar el orden de ejecución.
Si ya lograste que todos los botones respondan al clic, comparte tu solución: es un ejercicio excelente para reforzar el manejo dinámico del DOM con JavaScript.