Gắn trình xử lý sự kiện cho các phần tử mới trong JavaScript
Giả sử chúng ta có danh sách ul và một nút bấm:
<ul>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
<button>add</button>
Lấy các phần tử của chúng ta vào các biến tương ứng:
let button = document.querySelector('button');
let list = document.querySelector('ul');
let items = list.querySelectorAll('li');
Hãy làm sao cho khi nhấp vào bất kỳ li nào
một dấu chấm than sẽ được thêm vào cuối nó:
for (let item of items) {
item.addEventListener('click', function() {
this.textContent = this.textContent + '!';
});
}
Bây giờ hãy làm sao cho khi nhấn
vào nút, một phần tử
li mới sẽ được thêm vào cuối danh sách:
button.addEventListener('click', function() {
let item = document.createElement('li');
item.textContent = 'item';
list.appendChild(item);
});
Tuy nhiên, chúng ta sẽ gặp phải vấn đề: nhấp vào phần tử
li mới được thêm vào sẽ không dẫn đến
việc thêm dấu chấm than vào cuối.
Vấn đề là chúng ta chỉ thêm trình xử lý sự kiện nhấp chuột
vào những li đã tồn tại
ban đầu, nhưng không phải vào những phần tử mới.
Hãy sửa vấn đề này bằng cách gắn trình xử lý sự kiện nhấp chuột vào phần tử li mới:
button.addEventListener('click', function() {
let item = document.createElement('li');
item.textContent = 'item';
item.addEventListener('click', function() { // trình xử lý sự kiện nhấp chuột
this.textContent = this.textContent + '!';
});
list.appendChild(item);
});
Tuy nhiên, bây giờ mã của hàm xử lý bị trùng lặp
ở hai nơi - cho các phần tử li
tồn tại ban đầu và cho các phần tử mới. Hãy sửa điều này bằng cách tách
nó ra thành một hàm riêng biệt:
function handler() {
this.textContent = this.textContent + '!';
}
Sử dụng hàm của chúng ta để tránh trùng lặp mã:
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);
});
Vấn đề nhìn chung đã được giải quyết và chúng ta đã tránh được việc trùng lặp
mã của hàm xử lý. Tuy nhiên, việc gắn
các trình xử lý sự kiện vẫn phải được thực hiện
ở hai nơi: cả trong vòng lặp cho các phần tử
li hiện có, và khi nhấp vào nút. Trong bài học tiếp theo,
chúng ta sẽ phân tích cách để loại bỏ sự bất tiện này.