바닐라 자바스크립트를 이용한 Todo List 만들기 - 3

삭제 및 마크

이벤트 리스너를 추가해준다. ul태그 내에 li를 삭제하는 것이므로 todoList에 addEventListener 메서드를 추가한다.

todoList.addEventListener('click', deleteCheck');

이벤트 리스너를 추가했으면? deleteCheck 함수를 만들 차례.

function deleteCheck(e) {
	const item = e.target;
	//Delete Todo
	if (item.classList[0] === 'trash-btn') {
		const todo = item.parentElement;
		todo.remove();
	}

	if (item.classList[0] === 'complete-btn') {
		const todo = item.parentElement;
		todo.classList.toggle('completed');
	}
}

e.target을 이해하려면 Event Bubbling의 개념을 알아야 한다.
만약 하나의 웹사이트에 하나의 이벤트만 발생한다면 문제가 없겠지만 같은 이벤트라 하더라도 다르게 동작해야하는 것들이 많다.
이 근본적인 이유는 HTML 태그들이 중첩된 구조를 띄기 때문이다.

브라우저는 이벤트가 발생한 해당 태그의 콜백함수를 실행하고 상위 요소에 동일한 이벤트가 있는지 확인한다.
그 중 동일한 이벤트가 등록되어 있는 요소가 있다면 해당 콜백 함수를 실행한다.

이런 상위 이벤트의 전파는 e.stopPropagation()으로 막을 수 있다.

그렇다면 event target은 무엇인가?
event.target은 이벤트가 발생한 요소를 반환해주는 것이다.

예를들어 x라는 요소를 클릭했을 때 이벤트가 발생한다면, 이벤트가 발생할 때 마다 이벤트의 대상인 x요소를 콘솔창에 출력해준다.
event.target을 이용하면 현재 이벤트가 발생한 요소의 속성들을 얻을 수 있다.

즉 const item = e.target; 은 item은 현재 이벤트가 발생한 요소를 지칭하게 되는 것이다.
만약 이 요소를 변경하고 싶다면 item.style.color = "red"; 와 같은 DOM 메서드를 사용해야한다.

--

if (item.classList[0] === 'trash-btn')
: item의 첫번째 클래스가 trash-btn이라면

const todo = item.parentElement;
todo.remove();
: item.remove()를 하면 아이콘을 클릭했을 때 삭제가 되지 않는 문제가 생기기 때문에 todo 상수를 지정해서 item의 상위 요소에 remove를 한다.

6. 애니메이션

.completed {
	text-decoration: line-through;
	opacity: 0.5;
}

.fall {
	transform: translateY(8rem) rotateZ(20deg);
	opacity: 0;
}

.todo {
	margin: 0.5rem;
	background: white;
	color: black;
	font-size: 1.5rem;
	display: flex;
	justify-content: space-between;
	align-items: center;
	transition: all 0.3s ease;
}

function deleteCheck(e) {
	const item = e.target;
	//Delete Todo
	if (item.classList[0] === 'trash-btn') {
		const todo = item.parentElement;
		todo.classList.add('fall');
		todo.addEventListener('transitionend', function () {
			todo.remove();
		});
	}

	if (item.classList[0] === 'complete-btn') {
		const todo = item.parentElement;
		todo.classList.toggle('completed');
	}
}

7. 필터링

			<div class="select">
				<select name="todos" class="filter-todo">
					<option value="all">All</option>
					<option value="completed">Completed</option>
					<option value="uncompleted">Uncompleted</option>
				</select>
			</div>


function filterTodo(e) {
	const todos = todoList.childNodes;
	todos.forEach(function (todo) {
		switch (e.target.value) {
			case 'all':
				todo.style.display = 'flex';
				break;
			case 'completed':
				if (todo.classList.contains('completed')) {
					todo.style.display = 'flex';
				} else {
					todo.style.display = 'none';
				}
				break;
			case 'uncompleted':
				if (!todo.classList.contains('completed')) {
					todo.style.display = 'flex';
				} else {
					todo.style.display = 'none';
				}
				break;
		}
	});
}
//Selectors
const todoInput = document.querySelector('.todo-input');
const todoButton = document.querySelector('.todo-button');
const todoList = document.querySelector('.todo-list');
const filterOption = document.querySelector('.filter-todo');

//Event Listeners
todoButton.addEventListener('click', addTodo);
todoList.addEventListener('click', deleteCheck);
filterOption.addEventListener('click', filterTodo);

좋은 웹페이지 즐겨찾기