Supongamos que tengo un grupo de botones, cada uno de los cuales asigna un color diferente a un elemento en el que se hizo clic. Entonces, el botón rojo hace que el elemento en el que se hizo clic se vuelva rojo.
<div id="color-pickers"> <button id="red" class="picker"><span class="sr-only">red</span></button> <button id="orange" class="picker "><span class="sr-only">orange</span></button> <button id="yellow" class="picker"><span class="sr-only">yellow</span></button> ... </div>En lugar de escribir un controlador de eventos para cada uno, me gustaría escribir un controlador de eventos con nombre dinámico.
Hasta ahora, he intentado crear una matriz de nombres de colores:
const colors = ['red', 'orange', 'yellow', ...]luego recorriendo esa matriz:
for (i = 0; i < colors.length; i++) { // for each color in array, assign it to a button colors[i].addEventListener("click", function () { ... }); } Con la esperanza de terminar con red.addEventListener... , orange.addEventListener... etc. Pero en cambio, esto da como resultado: TypeError: colors[i].addEventListener is not a function .
He intentado usar literales de plantilla sin éxito. Esto parecía prometedor, pero no funcionó (posiblemente porque no estoy seguro de entender completamente lo que está pasando allí).
Gracias de antemano, y avíseme si puedo aclararlo.
para aclarar:
Estoy tratando de evitar escribir algo como:
red.addEventListener("click", function() { doSomething... }); orange.addEventListener("click", function() { doSomething... }); yellow.addEventListener("click", function() { doSomething... }); En cambio, quiero escribir la lista de colores una vez, luego usar esa lista para completar la parte que viene antes .addEventListener . Terminé usando la segunda parte de la respuesta de @Titulum, con la lista de botones existentes. Podría ir un paso más allá y crear los botones mediante programación también, pero por ahora, eso hace lo que quiero. Gracias a todos.
Puede crear los botones mediante programación y/o agregar un detector de eventos de la siguiente manera:
const buttonContainer = document.getElementById('button-container'); const target = document.getElementById('target'); const colors = [ "red", "blue", "yellow" ]; for (const color of colors) { const colorButton = document.createElement('button'); colorButton.innerText = color; colorButton.addEventListener('click', () => { target.style.backgroundColor = color; }); buttonContainer.appendChild(colorButton); } #target { width: 200px; height: 200px; background-color: red; } <div id="button-container"></div> <div id="target"></div>También puede agregar el detector de eventos a una lista de botones ya existente, siempre que los identificadores de los botones sigan un formato establecido:
const target = document.getElementById('target'); const colors = [ "red", "blue", "yellow" ]; for (const color of colors) { const button = document.getElementById(`button-${color}`); button.addEventListener('click', () => { target.style.backgroundColor = color; }); } #target { width: 200px; height: 200px; background-color: red; } <button id="button-red">red</button> <button id="button-blue">blue</button> <button id="button-yellow">yellow</button> <div id="target"></div>Esto sugiere que necesita integrar su HTML con su JS.
<!-- HTML --> <button class="color-button" id="pink">Pink</button> <button class="color-button" id="yellow">Yellow</button> <button class="color-button" id="cyan">Cyan</button> <!-- JS --> // add EventListener to each .color-button [].slice(document.getElementsByClassName("color-button")).forEach(button => { button.addEventListener("click", buttonHandler, !1) }); // use the id-attribute of each button to // set the button's background colour const = buttonHandler = (e) => { let target = e.target, color = target.id; target.style.bacgroundColor = color; };Puede usar addEventListener para un elemento html, no para una cadena.
Debe convertir su cadena a un elemento html para agregarle un detector de eventos.
Puede crear un objeto con sus nodos y asignarle detectores de eventos de clic.
const colors = ['red', 'orange', 'yellow']; const red = document.getElementById("red"); const orange = document.getElementById("orange"); const yellow = document.getElementById("yellow"); const nodeObj = { red, orange, yellow } for (i = 0; i < colors.length; i++) { // for each color in array, assign it to a button nodeObj[colors[i]].addEventListener("click", function (e) { console.log(`You clicked ${e.currentTarget.id}`) }); } <p id="red">Red</p> <p id="orange">Orange</p> <p id="yellow">Yellow</p>O
Puede hacer uso de eval para eso (Esta es una solución sucia).
const colors = ['red', 'orange', 'yellow']; const red = document.getElementById("red"); const orange = document.getElementById("orange"); const yellow = document.getElementById("yellow"); for (i = 0; i < colors.length; i++) { // for each color in array, assign it to a button eval(colors[i]).addEventListener("click", function (e) { console.log(`You clicked ${e.currentTarget.id}`) }); } <p id="red">Red</p> <p id="orange">Orange</p> <p id="yellow">Yellow</p>