Attacher des gestionnaires d'événements aux nouveaux éléments en JavaScript
Supposons que nous ayons une liste ul et un bouton :
<ul>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
<button>add</button>
Récupérons nos éléments dans les variables correspondantes :
let button = document.querySelector('button');
let list = document.querySelector('ul');
let items = list.querySelectorAll('li');
Faisons en sorte qu'un clic sur n'importe quelle li
ajoute un point d'exclamation à la fin :
for (let item of items) {
item.addEventListener('click', function() {
this.textContent = this.textContent + '!';
});
}
Faisons maintenant en sorte qu'un clic
sur le bouton ajoute une nouvelle
li à la fin de la liste :
button.addEventListener('click', function() {
let item = document.createElement('li');
item.textContent = 'item';
list.appendChild(item);
});
Cependant, nous obtiendrons un problème : un clic sur la nouvelle
li ajoutée n'ajoutera pas
de point d'exclamation à la fin.
Le fait est que nous ajoutons un gestionnaire de clic
uniquement aux li qui existaient
initialement, mais pas aux nouvelles.
Corrigeons le problème en attachant à la nouvelle li
un gestionnaire de clic :
button.addEventListener('click', function() {
let item = document.createElement('li');
item.textContent = 'item';
item.addEventListener('click', function() { // gestionnaire de clic
this.textContent = this.textContent + '!';
});
list.appendChild(item);
});
Cependant, maintenant le code de la fonction gestionnaire est dupliqué
à deux endroits - pour les li existant initialement
et pour les nouvelles. Corrigeons cela en le
extrayant dans une fonction séparée :
function handler() {
this.textContent = this.textContent + '!';
}
Utilisons notre fonction pour éviter la duplication de code :
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);
});
Le problème est en gros résolu et nous avons évité la duplication
du code de la fonction gestionnaire. Cependant, nous devons toujours attacher
les gestionnaires d'événements
à deux endroits : à la fois dans la boucle pour les li
existantes, et lors du clic sur le bouton. Dans la prochaine
leçon, nous verrons un moyen de nous débarrasser de cette
gêne.