바닐라 자바스크립트를 이용해서 모멘텀을 만들어보았다. 시계, 사용자 이름 기억, 투두 리스트, 명언, 날씨 등의 기능을 넣었다. 그 중 투두리스트 구현 부분의 코드를 아래 가져와봤다.
전체 코드는 아래 깃허브에서
https://github.com/Seohyun-Roh/vanilla_JS
GitHub - Seohyun-Roh/vanilla_JS: HTML, CSS, and JavaScript로 만든 Momentum입니다.
HTML, CSS, and JavaScript로 만든 Momentum입니다. Contribute to Seohyun-Roh/vanilla_JS development by creating an account on GitHub.
github.com
index.html
<!--~~-->
<form id="todo-form">
<input type="text" placeholder="+ Write a TODO!" required />
</form>
<ul id="todo-list">
<!-- <li>
<span></span>
<button></button>
</li> -->
</ul>
<!--~~-->
<script src="js/todo.js"></script>
todo.js
전체 코드
const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.getElementById("todo-list");
const TODOS_KEY = "todos";
let toDos = [];
function saveToDo(){
localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
}
function deleteToDo(e){
const li = e.target.parentElement;
li.remove();
toDos = toDos.filter(item => item.id !== parseInt(li.id));
saveToDo();
}
function paintToDo(newToDoObj){
const li = document.createElement("li");
li.id = newToDoObj.id;
const span = document.createElement("span");
span.innerText = newToDoObj.text;
const button = document.createElement("button");
button.innerText = "❌"
button.addEventListener("click", deleteToDo);
li.appendChild(span);
li.appendChild(button);
toDoList.appendChild(li);
}
function handleToDoSubmit(e){
e.preventDefault();
const newToDo = toDoInput.value;
toDoInput.value="";
const newToDoObj = {
text: newToDo,
id: Date.now()
}
toDos.push(newToDoObj);
paintToDo(newToDoObj);
saveToDo();
}
toDoForm.addEventListener("submit",handleToDoSubmit);
const savedToDos = localStorage.getItem(TODOS_KEY);
if(savedToDos){
const parsedToDos = JSON.parse(savedToDos);
toDos = parsedToDos;
parsedToDos.forEach(paintToDo);
}
코드 설명
변수 선언
const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.getElementById("todo-list");
const TODOS_KEY = "todos";
let toDos = [];
todo-form, input, todo-list를 html로부터 가져와서 변수에 넣어주고, 자주 쓰인 문자열 "todos"를 TODOS_KEY라는 변수에 저장을 해주었다. toDo를 배열로 만들어서 localStorage에 저장할 것이기 때문에 먼저 let 으로 빈 배열을 만들어주었다.
toDo Submit 이벤트 함수
function handleToDoSubmit(e){
e.preventDefault(); //submit했을 때 자동으로 새로고침되는 것을 막아줌
const newToDo = toDoInput.value; //새로 입력되는 toDo를 newToDo에 저장
toDoInput.value=""; //입력창을 비워줌
//이를 Object에 저장. todo들을 구분해주기 위해서 Date.now()를 이용해 랜덤으로 id를 지정
const newToDoObj = {
text: newToDo,
id: Date.now()
}
toDos.push(newToDoObj); //toDos배열에 Object를 push
paintToDo(newToDoObj); //새로운 요소 생성해주는 함수
saveToDo(); //localStorage에 저장
}
toDoForm.addEventListener("submit",handleToDoSubmit); //toDoForm에 submit EventListener를 추가
submit 이벤트가 발생하면 브라우저가 자동으로 새로고침되기 때문에 preventDefault()를 써서 자동으로 새로고침되는 것을 막아준다.
입력된 toDo를 Object 형태로 text에는 toDo 내용, id에는 Date.now()를 이용해 랜덤으로 id를 지정해준다.
그리고 todos 배열에 Object를 push해준 뒤, paintToDo 함수에 Object를 인자로 넘겨주어 html에도 toDo 요소들을 추가할 수 있도록 해주고, saveToDo 함수를 써서 현재 상태를 저장해준다.
새로운 요소를 생성해서 html에 추가해주는 함수
function paintToDo(newToDoObj){
const li = document.createElement("li");
li.id = newToDoObj.id; //li를 만들어서 인자로 받은 Object의 id를 li의 id로 저장
const span = document.createElement("span");
span.innerText = newToDoObj.text; //Object의 text(toDoInput.value)를 span의 innerText로 저장
const button = document.createElement("button");
button.innerText = "❌" //toDo 삭제하는 버튼 같이 추가
button.addEventListener("click", deleteToDo); //버튼에 click 이벤트 추가. 함수로 deleteToDo
li.appendChild(span);
li.appendChild(button);
toDoList.appendChild(li); //toDoList에 생성한 요소들을 추가해준다.
}
ul인 toDoList에 element를 넣어주기 위해서 li를 먼저 생성하고, 인자로 받아온 newToDoObj의 id를 li의 id로 지정해준다.
span에는 newToDoObj의 text를 저장해주고, 버튼을 만들어서 deleteToDo 이벤트 리스너를 추가해준다.
li안에 span과 button이 있기 때문에 li에 appendChild(span), appendChild(button)을 해준 뒤, 이렇게 만든 li를 toDoList에 추가해준다.
toDo를 localStorage에 저장해주는 함수
//localStorage에 key:todos, value:JSON.stringify(toDos)로 저장
function saveToDo(){
localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
}
localStorage에는 배열의 형태로는 저장할 수 없고 string형식으로 저장해야되기 때문에 JSON.stringify를 이용해서 toDos를 string으로 만들어주고 localStorage에 저장해준다.
저장되어있는 toDo를 지워주는 함수
function deleteToDo(e){
const li = e.target.parentElement;
li.remove(); //클릭 이벤트가 발생한 버튼의 부모 element를 html에서 제거
//toDos에서 li와 id가 같은 item을 제거
toDos = toDos.filter(item => item.id !== parseInt(li.id));
saveToDo(); //바뀐 내용으로 다시 저장
}
클릭 이벤트가 발생한 버튼의 부모 li를 html에서 제거해준 뒤, toDos배열에서 li와 id가 같은 요소를 제거해줘서 새로 배열을 만들어준다.
그리고 바뀐 내용을 업데이트 해준다.
처음에 toDos 배열을 빈 배열로 선언했기 때문에 처음에 열면 localStorage에는 저장되어있지만 페이지에는 안보이는 경우가 있다. 따라서 아래의 코드를 추가해준다.
//localStorage에 저장되어있는 todos를 불러옴
const savedToDos = localStorage.getItem(TODOS_KEY);
//todos에 item이 있을 경우
if(savedToDos){
const parsedToDos = JSON.parse(savedToDos); //저장된 toDo들을 배열의 형태로 저장
toDos = parsedToDos; //toDos에 불러온 toDo를 저장
parsedToDos.forEach(paintToDo); //parsedToDo배열의 모든 요소들을 그려준다.
}
localStorage에 저장되어있는 todos를 불러와서 만약 item이 있을 경우, 저장되어있던 string 형식의 toDo들을 JSON.parse를 이용해 배열의 형태로 바꿔준다.
이를 toDos배열에 넣어준 뒤, 그 요소들에 대해 forEach함수를 이용해 요소들을 그려줄 수 있도록 한다.
gh-page로 볼 수 있도록 올려놓았다. (css는 좀 못생겼지만 그래도) 잘 작동합니다!
https://seohyun-roh.github.io/vanilla_JS/
Momentum
seohyun-roh.github.io
'FE > Javascript' 카테고리의 다른 글
[JS] ES6의 특징 (1) - const와 let, 화살표 함수 (0) | 2022.02.28 |
---|---|
[JS] 호이스팅(Hoisting) (0) | 2022.02.19 |
[JS] filter 함수란? (0) | 2021.09.02 |
[HTML][JS] script 태그는 어디에 위치해야 할까? (0) | 2021.09.02 |
[JS] Array.from을 통한 배열 초기화 (0) | 2021.08.23 |