Закачане на манипулатори на нови елементи в JavaScript
Да предположим, че имаме списък ul и бутон:
<ul>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
<button>add</button>
Нека получим нашите елементи в съответните променливи:
let button = document.querySelector('button');
let list = document.querySelector('ul');
let items = list.querySelectorAll('li');
Нека направим така, че при кликване върху която и да е li
да се добавя удивителен знак в края:
for (let item of items) {
item.addEventListener('click', function() {
this.textContent = this.textContent + '!';
});
}
Сега нека направим така, че при натискане
на бутона в края на списъка да се добавя нов
li:
button.addEventListener('click', function() {
let item = document.createElement('li');
item.textContent = 'item';
list.appendChild(item);
});
Обаче ще срещнем проблем: кликването върху новодобавения
li няма да доведе
до добавяне на удивителен знак в края.
Факт е, че ние добавяме манипулатор за кликване
само за тези li, които са съществували
първоначално, но не и за новите.
Нека поправим проблема, като сложим манипулатор за кликване на новия li
:
button.addEventListener('click', function() {
let item = document.createElement('li');
item.textContent = 'item';
item.addEventListener('click', function() { // манипулатор за кликване
this.textContent = this.textContent + '!';
});
list.appendChild(item);
});
Сега обаче кодът на функцията-манипулатор се дублира
на две места - за първоначално съществуващите
li и за новите. Нека поправим това, като я изнесем
в отделна функция:
function handler() {
this.textContent = this.textContent + '!';
}
Нека използваме нашата функция, за да избегнем дублирането на кода:
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);
});
Задачата като цяло е решена и избегнахме дублирането
на кода на функцията-манипулатор. Въпреки това, да закачаме
манипулатори на събития все пак трябва
на две места: както в цикъла за съществуващите
li, така и при кликване на бутона. В следващия
урок ще разгледаме начин да се отървем от това
неудобство.