Asignar manejadores a nuevos elementos en JavaScript
Supongamos que tenemos una lista ul y un botón:
<ul>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
<button>add</button>
Obtengamos nuestros elementos en las variables correspondientes:
let button = document.querySelector('button');
let list = document.querySelector('ul');
let items = list.querySelectorAll('li');
Hagamos que al hacer clic en cualquier li
se agregue un signo de exclamación al final:
for (let item of items) {
item.addEventListener('click', function() {
this.textContent = this.textContent + '!';
});
}
Ahora hagamos que al hacer clic
en el botón se agregue un nuevo
li al final de la lista:
button.addEventListener('click', function() {
let item = document.createElement('li');
item.textContent = 'item';
list.appendChild(item);
});
Sin embargo, obtendremos un problema: el clic en la nueva
li agregada no resultará
en la adición de un signo de exclamación al final.
El hecho es que agregamos el manejador de clic
solo a aquellas li que existían
inicialmente, pero no a las nuevas.
Solucionemos el problema asignando a la nueva li
un manejador de clic:
button.addEventListener('click', function() {
let item = document.createElement('li');
item.textContent = 'item';
item.addEventListener('click', function() { // manejador de clic
this.textContent = this.textContent + '!';
});
list.appendChild(item);
});
Sin embargo, ahora el código de la función manejadora se duplica
en dos lugares: para las li
existentes inicialmente y para las nuevas. Arreglemos esto extrayendo
el código a una función separada:
function handler() {
this.textContent = this.textContent + '!';
}
Usemos nuestra función para evitar duplicar código:
for (let item of items) {
item.addEventListener('click', handler);
}
button.addEventListener('click', function() {
let item = document.createElement('li');
item.textContent = 'item';
item.addEventListener('click', handler);
list.appendChild(item);
});
En general, el problema está resuelto y hemos evitado duplicar
el código de la función manejadora. Sin embargo, asignar
manejadores de eventos todavía tenemos que hacerlo
en dos lugares: tanto en el bucle para las li
existentes, como en el clic del botón. En la siguiente
lección, analizaremos una forma de deshacernos de esta
molestia.