JavaScript에서 새로운 요소에 이벤트 핸들러 추가하기
ul 목록과 버튼이 있다고 가정해 봅시다:
<ul>
<li>항목</li>
<li>항목</li>
<li>항목</li>
<li>항목</li>
<li>항목</li>
</ul>
<button>추가</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 = '항목';
list.appendChild(item);
});
그러나 문제가 발생합니다: 새로 추가된
li를 클릭해도 끝에 느낌표가 추가되지 않습니다.
그 이유는 클릭 이벤트 핸들러를 처음부터 존재했던
li에만 추가했기 때문입니다. 새로운 요소에는 추가하지 않았습니다.
새로운 li에도 클릭 핸들러를 추가하여 문제를 해결해 봅시다:
button.addEventListener('click', function() {
let item = document.createElement('li');
item.textContent = '항목';
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.addEventListener('click', handler);
list.appendChild(item);
});
문제는 기본적으로 해결되었고 핸들러 함수 코드의 중복은 피했습니다.
그러나 여전히 이벤트 핸들러를 두 곳(기존 li를 위한 루프와 버튼 클릭 시)에
추가해야 합니다. 다음 강의에서는 이 불편함을 해결하는 방법을 알아보겠습니다.