VanillaJS 를 이용해서 간단한 투두리스트를 만드는 방법 기록
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Todo List w/ vanillaJS</title>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<div class="todo-container">
<h1>My Todo List</h1>
<input type="text" id="todo-input" placeholder="할 일을 추가하세요" />
<button id="add-todo">+</button>
<ul id="todo-list"></ul>
</div>
<script src="index.js"></script>
</body>
</html>
document.addEventListener('DOMContentLoaded', () => {
const addButton = document.getElementById('add-todo');
const inputField = document.getElementById('todo-input');
const todoList = document.getElementById('todo-list');
addButton.addEventListener('click', function() {
const todoText = inputField.value.trim();
if (todoText !== '') {
const listItem = document.createElement('li');
listItem.textContent = todoText;
// 삭제 버튼 추가
const deleteButton = document.createElement('button');
deleteButton.textContent = 'Delete';
deleteButton.onclick = function() {
listItem.remove();
};
listItem.appendChild(deleteButton);
todoList.appendChild(listItem);
inputField.value = ''; // 입력 필드 초기화
}
});
inputField.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
addButton.click(); // Enter 키로 추가 버튼 활성화
}
});
});
document.addEventListener('DOMContentLoaded', () => {
// 코드
});
웹 페이지의 DOM이 완전히 로드되고 파싱되었을 때 실행되어야 하는 스크립트를 감싸는 데 사용.
즉, 안에 있는 코드는 페이지의 HTML이 완전히 로드된 후에 실행되기 시작한다.
이는 HTML 요소에 접근하려고 할 때 해당 요소들이 이미 로드되어 있음을 보장함!
const addButton = document.getElementById('add-todo');
const inputField = document.getElementById('todo-input');
const todoList = document.getElementById('todo-list');
document.getElementById
메소드를 사용해 HTML 파일에서 특정 ID를 가진 요소들을 선택한다.
addButton.addEventListener('click', function() {
//
});
'Add' 버튼(addButton
)에 클릭 이벤트 리스너를 추가.
해당 버튼이 클릭될 때마다 입력 필드(inputField
)에서 텍스트를 가져와 To-Do 항목을 생성하는 함수가 실행된다.
const todoText = inputField.value.trim();
if (todoText !== '') {
const listItem = document.createElement('li');
listItem.textContent = todoText;
const deleteButton = document.createElement('button');
deleteButton.textContent = 'Delete';
deleteButton.onClick = function() {
listItem.remove();
};
listItem.appendChild(deleteButton);
todoList.appendChild(listItem);
inputField.value=''; // 입력 필드 초기화
}
trim()
메소드를 사용해 앞뒤 공백을 제거한 후 변수 todoText
에 저장한다.todoText
가 비어있지 않다면(todoText !== ''
), 새로운 <li>
요소를 생성하고, 사용자의 입력한 텍스트를 그 내용으로 설정한다.<button>
요소를 생성하고 'Delete' 라는 텍스트를 넣는다. listItem
)을 삭제하는 함수를 onClick
이벤트 리스너로 추가한다.(deleteButton.onclick = function() { listItem.remove(); };
)<li>
요소에 추가하고(listItem.appendChild(deleteButton)
), 이 <li>
요소를 전체 To-Do 리스트(todoList
)에 추가한다.(todoList.appendChild(listItem)
)inputField.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
addButton.click(); // Eneter 키로 추가 버튼 활성화
}
});
사용자가 입력 필드(inputField
)에서 Enter 키를 누르면 'Add' 버튼(addButton
)이 클릭되도록 한다.
keypress
이벤트를 감지하고 눌린 키가 'Enter'인 경우에 addButton.click()
을 호출하여 로직을 실행한다.
이렇게 하니까 새로고침 할 때마다 작성한 투두리스트가 삭제되고 초기 상태로 돌아가는 문제가 생겼다. 그래서
local Storage
를 활용해서 새로고침을 해도 투두리스트가 유지되게끔 하는 코드를 새로 추가해주기로 했다.
addTodo(), loadTodos(), saveTodos()
추가
document.addEventListener("DOMContentLoaded", () => {
const addButton = document.getElementById("add-todo");
const inputField = document.getElementById("todo-input");
const todoList = document.getElementById("todo-list");
// 페이지 로드 시 To-do 리스트 로드
loadTodos();
addButton.addEventListener("click", function () {
// 사용자 입력값 투두 리스트 항목 추가
const todoText = inputField.value.trim();
if (todoText !== "") {
addTodo(todoText);
saveTodos();
inputField.value = "";
}
});
inputField.addEventListener("keypress", function (e) {
if (e.key === "Enter") {
addButton.click();
}
});
function addTodo(todoText) {
const listItem = document.createElement("li");
listItem.textContent = todoText;
// 삭제 버튼 추가
const deleteButton = document.createElement("button");
deleteButton.textContent = "X";
deleteButton.onclick = function () {
listItem.remove();
saveTodos(); // 항목을 삭제할 때도 변경사항 저장
};
listItem.appendChild(deleteButton);
todoList.appendChild(listItem);
}
// local Storage에서 To-do 리스트 로드
function loadTodos() {
const todos = JSON.parse(localStorage.getItem("todos")) || [];
todos.forEach((todoText) => {
addTodo(todoText);
});
}
// local Storage에 To-do 리스트 저장
function saveTodos() {
const todos = [];
document.querySelectorAll("#todo-list li").forEach((item) => {
const todoText = item.textContent.replace("Delete", "").trim();
todos.push(todoText);
});
localStorage.setItem("todos", JSON.stringify(todos));
}
});
// To-Do 항목을 추가하는 함수
function addTodo(todoText) {
const listItem = document.createElement('li');
listItem.textContent = todoText;
const deleteButton = document.createElement('button');
deleteButton.textContent = 'Delete';
deleteButton.onclick = function() {
listItem.remove();
saveTodos(); // 항목을 삭제할 때도 변경사항 저장
};
listItem.appendChild(deleteButton);
todoList.appendChild(listItem);
}
addButton
의 이벤트리스너 안에 있던 로직을 addTodo()
함수로 정의하여 호출한다.
// 로컬 스토리지에서 To-Do 리스트 로드
function loadTodos() {
const todos = JSON.parse(localStorage.getItem('todos')) || [];
// 코드
});
}
로컬 스토리지에서 'todos'키에 해당하는 값을 가져온다. 저장된 값이 없으면 빈 배열([]
)을 사용한다.
JSON.parse
는 문자열 형태의 데이터를 자바스크립트 객체로 변환시켜준다.
todos.forEach(todoText => {
addTodo(todoText);
})
todos
배열의 각 항목(todoText
)에 대해 addTodo
함수를 호출한다.
이 함수는 새로운 To-Do 항목을 추가한다.
// local Storage에 To-do 리스트 저장
function saveTodos() {
const todos = [];
// 코드
}
새로운 빈 배열 todos
를 생성한다. -> 이 배열은 로컬 스토리지에 저장될 To-Do 항목들의 텍스트를 담게 된다.
document.querySelectorAll("#todo-list li").forEach((item) => {
const todoText = item.textContent.replace("Delete", "").trim();
todos.push(todoText);
});
페이지의 모든 To-Do 항목(#todo-list li
)을 순회한다.
각 항목의 텍스트 내용에서 'Delete' 문자열을 제거하고 앞뒤 공백을 제거한 뒤, 결과 텍스트(todoText
)를 todos
배열에 추가한다.
localStorage.setItem("todos", JSON.stringify(todos));
최종적으로 todos
배열을 JSON 문자열로 변환한 후 'todos' 키를 사용하여 로컬 스토리지에 저장한다.
JSON.stringify
는 자바스크립트 객체를 문자열 형태로 변환한다.
💡 이제 새로고침을 해도 local storage에 todos 내용이 저장되어 있기 때문에 투두 리스트 항목이 그대로 유지가 된다!