우리가 웹 서핑을 하다 보면 아이디를 저장하거나, 장바구니에 담은 물건이 다음날에도 그대로 남아있는 것을 볼 수 있습니다. 반면, 우리가 지난번 만든 스톱워치는 페이지를 새로고침하는 순간 모든 기록이 0으로 돌아갔죠. 오늘 만들 자바스크립트 할 일 목록(To-do List)은 바로 이 차이를 해결하는 프로젝트입니다.
앞서 우리가 만든 ‘OX 퀴즈‘와 ‘스톱워치’가 브라우저의 현재 상태(State)를 보여주는 데 집중했다면, 이번 프로젝트는 한 단계 더 나아가 “데이터를 어떻게 보존할 것인가?”라는 웹 애플리케이션의 핵심 과제를 다룹니다. 단순히 화면에 글자를 띄우는 법을 넘어, 브라우저의 저장 공간을 빌려 데이터를 반영구적으로 보관하는 법을 배워보겠습니다. 이 기술을 익히면 여러분은 이제 ‘휘발성 페이지’가 아닌 ‘실제 쓸모 있는 웹 서비스’를 만들 수 있게 됩니다.

1. 설계
이번 프로젝트의 핵심은 개발 용어로 CRUD(Create, Read, Update, Delete)를 이해하는 데 있습니다.
- Create: 사용자가 입력한 할 일을 새로운 리스트 아이템으로 생성합니다.
- Read: 저장된 데이터 배열을 읽어와 화면에 뿌려줍니다.
- Update: 완료된 할 일에 취소선을 긋거나 체크 상태를 변경합니다.
- Delete: 필요 없는 목록을 삭제하고 데이터에서도 지웁니다.
2. HTML
HTML 코드는 간단합니다.
텍스트를 입력할 수 있는 input 태그와 입력한 내용을 추가할 버튼, 추가한 내용을 리스트 형태로 보여줄 수 있는 요소만 있으면 됩니다.
입력한 내용을 추가하는 부분은 자바스크립트 코드로 작성하고, 추가할 것이기 때문입니다.

3. LocalStorage와 JSON
처음에는 단순히 목록을 추가하는 기능만 구현했는데, 브라우저를 새로고침하면 데이터가 사라지는 문제가 있었습니다. 이를 해결하기 위해 LocalStorage를 활용해 데이터를 저장하고 불러오는 로직을 추가했습니다. 자바스크립트 입문자라면 이 과정을 통해 브라우저 저장소의 개념을 확실히 잡으실 수 있을 겁니다.
이번 프로젝트의 주인공은 LocalStorage입니다. 이는 브라우저가 제공하는 작은 창고 같은 공간인데, 한 가지 까다로운 점이 있습니다. 바로 ‘문자열(String)’만 저장할 수 있다는 것이죠.
하지만 우리가 관리할 할 일 목록은 여러 개(배열)이고, 각 할 일은 ‘내용’과 ‘완료 여부’를 가진 객체 형태여야 합니다. 이때 필요한 것이 바로 JSON.stringify()와 JSON.parse()입니다. 복잡해 보이지만 원리는 간단합니다.
- 저장할 때: 객체를 기계가 읽기 좋은 긴 문자열로 변환합니다.
- 불러올 때: 그 문자열을 다시 우리가 다루기 쉬운 자바스크립트 객체로 되돌립니다.
4. 자바스크립트 할 일 목록(To-do List) 코드
– LocalStorage: 브라우저 속 작은 데이터베이스
앞서 말했듯이, 이번 글의 핵심은 localStorage입니다. localStorage.setItem()과 getItem()을 활용해 사용자의 할 일을 텍스트 형태가 아닌 JSON 객체 배열로 저장하고 불러오기를 실행합니다. 아래의 코드처럼 myTodos라는 이름으로 저장되어 있는 데이터를 가져오고, 저장할 때도 같은 이름으로 저장하면 됩니다.
let todos = JSON.parse(localStorage.getItem('myTodos')) || [];
...
function saveAndRender() {
localStorage.setItem('myTodos', JSON.stringify(todos));
renderTodos();
}
– 이벤트 위임(Event Delegation) 기법
목록이 100개라면 버튼 100개에 각각 이벤트를 걸어야 할까요? 할 일을 추가할 때마다 삭제 버튼에 일일이 이벤트를 거는 것은 비효율적입니다. 그래서 우리는 ‘이벤트 위임(Event Delegation)’이라는 고급 기술을 쓸 거예요. 할 일들이 담기는 큰 주머니(<ul>)에만 감시자를 세워두고, 클릭된 대상이 ‘삭제 버튼’인지 ‘체크박스’인지 판단해서 처리하는 방식입니다. 이 방식은 코드도 깔끔해지고 성능도 훨씬 좋아집니다.
function toggleTodo(id) {
todos = todos.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
);
saveAndRender();
}
function renderTodos() {
todoList.innerHTML = "";
todos.forEach(todo => {
const li = document.createElement('li');
li.innerHTML = `
<input type="checkbox" ${todo.completed ? 'checked' : ''} onchange="toggleTodo(${todo.id})">
<span class="todo-text ${todo.completed ? 'completed' : ''}">${todo.text}</span>
<button class="delete-btn" onclick="deleteTodo(${todo.id})">삭제</button>
`;
todoList.appendChild(li);
});
}
5. 자바스크립트 할 일 목록(To-do List) 실행 화면

5. 추가 사항
- 빈 값 체크: 사용자가 실수로 공백만 입력하고 추가를 누르는 것을 방지하는 로직(trim() 함수)을 추가했습니다.
- ID 값의 중요성: 각 할 일에 Date.now()를 이용해 고유 ID를 부여했습니다. 이는 나중에 데이터베이스를 다룰 때 매우 중요한 ‘Primary Key’ 개념과 연결됩니다.
6. 보완하면 좋은 점
- 삭제 시 시각적 효과: 할 일이 지워질 때 단순히 사라지는 것이 아니라 부드럽게 페이드아웃(Fade-out)되는 CSS 코드를 적용하여 웹 앱의 완성도를 높입니다.
- 필터링 기능: ‘전체 보기’, ‘할 일’, ‘완료된 일’ 세 가지 카테고리로 나누어 관리하는 기능을 추가해 보세요.
- 다크 모드 지원: 사용자 설정에 따라 테마가 변하는 기능을 넣으면 포트폴리오로서의 가치도 상승합니다.
- 날짜 데이터 활용: 각 할 일에 생성 날짜를 기록하고 마감 기한 알림 기능을 고민해 보는 것도 좋은 공부가 됩니다.
오늘은 자바스크립트 할 일 목록(To-do List)에 대해서 포스팅을 작성해 보았습니다. 브라우저를 닫아도 사라지지 않는 데이터를 다루게 되었습니다. 오늘 공부한 LocalStorage와 JSON 처리는 현대 웹 개발에서 거의 모든 곳에 쓰이는 기초 중의 기초입니다. JSON 처리와 localStorage 활용법은 나중에 백엔드 데이터베이스를 다룰 때도 기초가 되는 아주 중요한 개념입니다. 이 프로젝트에서 사용한 데이터 저장 로직은 나중에 만들 [자바스크립트 가계부 프로젝트]에도 동일하게 응용되니 꼭 익혀두세요!
코딩은 결국 ‘문제 해결의 연속’인 것 같습니다. 오늘 만든 이 리스트가 누군가에게는 단순한 연습장이겠지만, 우리에게는 데이터를 다루는 법을 깨닫게 해준 소중한 첫 번째 데이터베이스인 셈이죠. 여기서 멈추지 않고, 다음에는 이 목록을 더 예쁘게 꾸며보거나 더 복잡한 기능을 덧붙여보며 각자의 색깔이 담긴 멋진 앱으로 발전시켜 나갔으면 좋겠습니다.