돔요소를 바닐라 자바스크립트로 다뤄보았다.
렌더링을 할 때 innerHTML 을 사용해서 렌더링을 할 경우, 기존에 있는 내용들을 모두 지우고 다시 DOM을 만드는 비효율성 발생이 1번 문제,
sort의 결합도가 너무 높은 문제
함수 명이 이해하기 힘든 문제
콜백함수를 분리함으로서 이름을 하나 더 만들어내는 문제들이 있었다.
이를 해결하는 것을 고민해야 한다.
<script>
// 돔 요소
const $addInput = document.querySelector('#add-todo');
const $addForm = document.querySelector('form');
const $todos = document.querySelector('.todos');
// 상태 데이터
let todos = [
{ id: 1, content: 'html', completed: false },
{ id: 2, content: 'css', completed: true },
{ id: 3, content: 'js', completed: false },
];
const render = () => {
const newTodos = todos
.sort((todo1, todo2) => todo2.id - todo1.id)
.reduce((accumulator, { id, content, completed }) => {
accumulator += `
<li id="${id}">
<input type="checkbox" ${completed ? 'checked' : ''}/>
<span>${content}</span>
<button class="remove">X</button>
</li>
`;
return accumulator;
}, '');
$todos.innerHTML = newTodos;
};
render();
// 상태 변경 함수
const addTodo = content => {
todos = [{ id: todos[0].id + 1, content, completed: false }, ...todos];
render();
};
const removeTodo = id => {
todos = todos.filter(todo => todo.id !== +id);
render();
};
const checkTodo = id => {
todos = todos.map(todo => todo.id === +id ? { ...todo, completed: !todo.completed } : todo);
render();
};
// 이벤트 핸들러 콜백 함수
const addSubmitEvent = e => {
e.preventDefault();
const content = $addInput.value.trim();
if (!content) {
$addInput.value = '';
return;
}
addTodo(content);
$addInput.value = '';
};
const removeTodoEvent = e => {
if (e.target.matches('input[type=checkbox]')) return;
removeTodo(e.target.parentNode.id);
};
const checkTodoEvent = e => {
if (e.target.matches('button > .remove')) return;
checkTodo(e.target.parentNode.id);
};
// 이벤트 핸들러
$addForm.addEventListener('submit', addSubmitEvent);
$todos.addEventListener('click', removeTodoEvent);
$todos.addEventListener('change', checkTodoEvent);
</script>
노력하는 모습이 아름답습니다람쥐 ...^^...