
todo-list 삭제 버튼에 추가한 이벤트가 제대로 적용되는지 확인하려는데 html 파일을 실행하자마자 콘솔에 빨간 불이 들어왔다.
미리 버튼을 추가해두고 테스트했을 때는 발생하지 않았는데, 기존에 있던 테스트용 요소들을 모두 지우고 실행했을 때 발생하는 것으로 보아 addEventListener는 버튼이 생기기도 전에 호출되는데 해당 아이디를 가진 object가 없으니 이런 오류가 나는구나 추측이 됐다.
알아야 할 것
동적으로 생성한 요소에 이벤트를 추가하기 위해 생각해야하는 것은 다음과 같다.
1) addEventListener는 EventTarget 인터페이스의 메서드로, 가장 일반적으로 DOM 객체에 어떤 이벤트가 발생했을 때 어떤 동작을 수행할지 설정하는 기능을 한다.
2) createElement를 통해 DOM 객체를 생성할 수 있다.
사실 1)만 정확하게 알았어도 덜 헤맸을 것 같다..
내가 사용하는 메서드가 무슨 일을 하는지 정확히 아는 것이 중요하다는 생각이 들었다.
처음 시도한 방법
// task 추가
const taskAddButton = document.querySelector('#taskAddButton');
taskAddButton.addEventListener("click", addTask);
const taskList = document.querySelector('#list');
const taskInput = document.querySelector('#taskInput');
function addTask() {
let newTask = taskInput.value;
console.log(taskList.children.length + 1);
let newLi = `
<li class="task">
<input type="checkbox" name="task" id="task${taskList.children.length + 1}">
<label for="task${taskList.children.length + 1}">${newTask}</label>
<button class="taskDeleteButton"></button>
</li>
`;
taskList.innerHTML += newLi;
taskInput.value = '';
}
// task 삭제
const taskDeleteButton = document.querySelector('.taskDeleteButton');
taskDeleteButton.addEventListener("click", deleteTask);
function deleteTask(e) {
e.target.parentElement.remove();
}
제일 처음 작성했던 방법이다. 처음 파일을 실행하면 taskDeleteButton 클래스를 가진 요소가 없기때문에 오류가 발생한다.
저 상태로의 버튼은 단순히 문자열의 일부인데, addEventListener를 추가하기 위해 어떻게 DOM 객체로 받을 수 있을지 고민했다.
바꾼 방법
// task 추가
const taskAddButton = document.querySelector('#taskAddButton');
taskAddButton.addEventListener("click", addTask);
const taskList = document.querySelector('#list');
const taskInput = document.querySelector('#taskInput');
function addTask() {
let newTask = taskInput.value;
let newLi = document.createElement('li');
newLi.className = "task";
newLi.innerHTML = `
<input type="checkbox" name="task" id="task${taskList.children.length + 1}">
<label for="task${taskList.children.length + 1}">${newTask}</label>
`;
let deleteButton = document.createElement('button');
deleteButton.className = "taskDeleteButton";
deleteButton.addEventListener("click", deleteTask);
newLi.appendChild(deleteButton);
taskList.appendChild(newLi);
taskInput.value = '';
}
// task 삭제
function deleteTask(e) {
e.target.parentElement.remove();
}
새로운 할 일을 입력했을 때 html 요소를 문자열로 추가하던 방식에서 DOM 객체를 생성해 추가하는 방식으로 변경했다!
그리고 생성한 DOM 객체를 받아 이벤트를 설정해준 뒤 할일 목록에 추가해줬다.

목표대로 기능이 구현됐다!
정리
1) 요소를 생성할 때 문자열 -> html으로 변환하며 추가하지 않고 EventTarget이 구현되어있는 DOM 객체로 생성한다.
2) 생성한 객체에 이벤트를 설정한다.
* 이벤트 설정 -> 원하는 위치에 추가 / 원하는 위치에 추가 -> 이벤트 설정 순서는 상관없다! 이미 생성된 객체를 변수에 받아두었기 때문이다.
참고자료
MDN, EventTarget.addEventListener()
EventTarget.addEventListener() - Web API | MDN
EventTarget 인터페이스의 addEventListener() 메서드는 지정한 유형의 이벤트를 대상이 수신할 때마다 호출할 함수를 설정합니다.
developer.mozilla.org
'JavaScript' 카테고리의 다른 글
[JavaScript / jQuery] 특정 요소의 상/하단 위치 가져오기 (0) | 2024.07.16 |
---|---|
[JavaScript] 특정 위치로 스크롤 이동시키기 (scrollTo) (1) | 2024.07.16 |
Javascript에서 false로 간주되는 값들 (falsy) (0) | 2024.07.01 |
DOM이란 무엇일까? (0) | 2024.06.29 |
[jQuery] 간단한 메뉴바 만들기 (클릭한 요소 스타일 바꾸기) (0) | 2024.06.24 |