1. 복기
- 지난 시간에 간단하게 지역저장소(Local Storage)에 대해서 알아보았다.
- 지역저장소란, 브라우저가 제공하는 일종의 DB이며, JS를 이용해 접근 및 통제하여 브라우저를 운영하는데 필요한 정보를 사용자 측에 저장하는 것을 의미한다.
- 이번 포스팅에서는 지역저장소에 정보를 저장하고 저장된 정보를 활용하는 방법을 다루려고한다.
- 이를 위해, 저장 및 삭제 기능을 갖는 간단한 toDoList를 만들어보자.
2. 기본코드
- 지난 포스팅에서 사용했던 코드를 그대로 이어서 사용해보자.
- 추가된 사항은 다음과 같다.
- toDoList를 만들기 위해, 입력란이 필요하다. → input태그
- input태그에 입력된 정보를 활용해야 한다. → form태그
- toDoList는 여러개의 입력을 받을 수 있어야 한다. → ul태그
- 사용자가 할일(toDo)을 입력하면 이를 리스트로 출력해야 한다. → li태그
[HTML 코드]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vanilla JS</title>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<div class="js-clock">
<h1>00:00</h1>
</div>
<form class="js-form form">
<input type="text" placeholder="What is your name?"/>
</form>
<h4 class="js-greetings greetings"></h4>
<form class="js-toDoForm">
<input type="text" placeholder="Write what you need to do."/>
</form>
<ul class="js-toDoList"></ul>
<!-- Script 태그는 Body태그의 가장 마지막에 위치한다. -->
<script src="index.js"></script>
<script src="clock.js"></script>
<script src="greeting.js"></script>
<script src="todo.js"></script>
</body>
</html>
- 앞으로 작성할 JS코드는 todo.js라는 파일에 작성할 예정이다.
[출력화면]
3. 지역저장소 활용 전에 필요한 기능 구현
- 지역저장소를 활용하기에 앞서, input태그에 입력된 내용이 출력되도록 만들자.
- 구현할 내용의 순서는 다음과 같다.
1) querySelector를 이용해 정보를 가져오거나 사용할 HTML 엘리먼트를 객체화
const toDoForm = document.querySelector(".js-toDoForm");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.querySelector(".js-toDoList");
2) input에 입력(submit)에 반응하는 eventHandler
- input태그에서 submit 동작이 실행되면 해당 정보가 다른곳으로 전송된다.
- 현재 지역저장소를 사용하고 있지 않기때문에, submit기능이 작동되면 웹페이지가 새로고침되므로
- submit기능이 작동되지 않도록 한다.
function handleSubmit(event) {
event.preventDefault(); // 엔터를 눌러도 submit이 작동하지 않도록 기본 기능을 정지시킴
const currentValue = toDoInput.value;
paintToDo(currentValue);
toDoInput.value = "";
}
3) input태그에서 입력된 값을 HTML에서 li태그를 이용해 출력하는 함수
- ul 태그 아래에 자식태그 형태로 li태그가 삽입되어야 한다.
function paintToDo(text) {
const li = document.createElement("li"); // li 생성(엘리먼트를 생성시키는 함수 )
const delBtn = document.createElement("button"); //버튼 생성
const span = document.createElement("span");
delBtn.innerText = "❌";
span.innerText = text;
li.appendChild(span); // li 태그 내부에 자식태그를 생성하는 함수
li.appendChild(delBtn);
toDoList.appendChild(li);
}
[여기까지 전체코드]
const toDoForm = document.querySelector(".js-toDoForm");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.querySelector(".js-toDoList");
function paintToDo(text) {
const li = document.createElement("li"); // li 생성(엘리먼트를 생성시키는 함수 )
const delBtn = document.createElement("button"); //버튼 생성
const span = document.createElement("span");
delBtn.innerText = "❌";
span.innerText = text;
li.appendChild(span); // li 태그 내부에 자식태그를 생성하는 함수
li.appendChild(delBtn);
toDoList.appendChild(li);
}
function handleSubmit(event) {
event.preventDefault(); // 엔터를 눌러도 submit이 작동하지 않도록 기본 기능을 정지시킴
const currentValue = toDoInput.value;
paintToDo(currentValue);
toDoInput.value = "";
}
function init() {
//loadToDos();
toDoForm.addEventListener("submit", handleSubmit);
}
init();
[출력화면]
4. 지역저장소를 활용한 기능 구현
- 이제 기본적인 틀은 갖추어졌다. 그러므로, 지역저장소를 활용하여 input태그에서 입력된 정보들을 활용해보자.
1) 지역저장소에서 사용할 key값을 설정 및 지역저장소에서 해당 key값을 가져오는 함수
const TODOS_LS = 'toDos'; // 지역저장소에 저장될 value에 대응하는 key값을 설정
function loadToDos() { // 지역저장소에 저장된 key값의 value를 불러오는 function
const loadedToDos = localStorage.getItem(TODOS_LS);
}
function init() {
loadToDos(); // 함수를 만든 후, 반드시 호출해야 한다.
toDoForm.addEventListener("submit", handleSubmit);
}
init();
- 여기까지 지역저장소를 사용할 준비가 완료되었다.
- input태그에 입력된 값들이 li태그로 잘 출력되는 것을 확인하였고, 지역저장소에서 사용할 key값 설정 및 해당 key값을 불러오는 기능까지 완성하였다.
- 이제 남은 기능은 input태그에서 입력된 정보들을 지역저장소에 저장하는 삽입기능과 원하는 정보를 삭제하는 기능만이 남았다.
- 여기서 몇가지 고려사항이 있다. 저장할 데이터(할 일)는 여러개인데 사용하는 key는 1개라는 것이다.
- 사용자가 몇개의 할일을 기록할지 모르기때문에 key값을 미리 만들어 놓는 것은 공간복잡도의 관점에서 비효율적이다.
- 그러나 key값을 1개만 사용하면 사용자가 특정 데이터(할 일)을 삭제할 때, 여러개의 li태그 중 해당 데이터를 담고 있는 li태그를 어떻게 구분할 것인가에 대한 문제도 발생한다. 어떻게 해결할 수 있을까? - 배열과 객체를 사용하여 이 문제를 해결할 수 있다.
2) 지역저장소를 활용한 할일(toDo) 데이터 저장 및 삭제기능
- 배열을 이용하여 1개의 key가 여러개의 value를 저장할 수 있도록 한다.
- 데이터(할 일)을 삭제할 때, 데이터간의 구분을 위해 li태그에 id값을 설정한다.
- 이를 종합하여, value에는 사용자가 입력한 내용(text)과 해당 내용을 구분할 수 있는 id값을 부여한다.
const toDos = []; // toDo를 저장할 리스트 생성
function saveToDos() { // 배열(toDos)을 지역저장소에 저장하는 함수
localStorage.setItem(TODOS_LS, toDos);
}
function paintToDo(text) {
const li = document.createElement("li"); // li 생성(엘리먼트를 생성시키는 함수 )
const delBtn = document.createElement("button"); //버튼 생성
const span = document.createElement("span");
const newId = toDos.length + 1;
delBtn.innerText = "❌";
span.innerText = text;
li.appendChild(span); // li 태그 내부에 자식태그를 생성하는 함수
li.appendChild(delBtn);
toDoList.appendChild(li);
li.id = newId; // li태그를 삭제할 때, 어떤 li태그를 삭제할 것인지 구분하기 위해 id속성값을 부여
const toDoObj = { // toDos 배열안에 넣을 정보를 setup
text: text,
id: newId
};
toDos.push(toDoObj); // setup된 정보를 배열에 push
saveToDos(); // toDos를 지역저장소에 저장하는 함수를 호출
}
* 지역저장소에는 key와 value를 한 쌍의 형태로 데이터를 저장한다. 그러나 value는 string 외의 다른 자료형을 가질수 없다. saveToDos() 함수를 보면 toDoObj라는 객체를 지역저장소에 저장한 것을 확인할 수 있다. 만약 이대로 사용한다면 어떻게 출력될까?
[출력화면]
- 아래 사진을 보면 toDos에는 입력된 데이터가 Object형태로 잘 저장된 것을 확인할 수 있다.
- 그러나 지역저장소에는 [object Object] 라는 이름으로 3개의 데이터가 저장되어 있는 것을 볼 수 있다.
- 이렇게 저장되면 지역저장소에서 해당 value를 불러와서 다시 사용할 수가 없다. 어떻게 해결할까?
3) JSON을 이용한 Object(객체) 형변환
- JSON(JavaScript Object Notation)이란, 자바스크립트를 이용하여 Object(객체)를 다룰 수 있도록 하는 기술이다.
- JSON을 이용하면 Object를 지역저장소에 저장할 수 있는 string(문자열)형태로 형변환 할 수 있으며, 반대로 string을 Object로 복원할 수도 있다.
- 그러므로 해당 Object(객체)를 저장할 때는 string으로 형변환하여 저장하고, 저장된 value를 불러올 때는 다시 Object로 형변환 하는 코드를 작성해야 한다.
function saveToDos() { // 저장할 때, object를 string으로 형변환
// JSON.stringify()를 이용하면 object를 string으로 형변환할 수 있다.
localStorage.setItem(TODOS_LS, JSON.stringify(toDos));
}
function loadToDos() {
const loadedToDos = localStorage.getItem(TODOS_LS);
if (loadedToDos !== null) {
const parsedToDos = JSON.parse(loadedToDos);
// 스트링으로 바뀌어 저장되어있는 value를 불러와서 사용해야 하므로
// JSON을 활용하여 string을 다시 object로 형변환 시켜준다.
}
}
4) forEach를 사용하여 리스트의 요소를 출력하기
- 위의 코드에서 toDos라는 이름의 리스트를 사용하여 여러개의 데이터를 저장한 것을 확인할 수 있다.
- 이 리스트에 저장된 각각의 데이터를 추출해야만 온전히 사용할 수 있으므로 그 과정을 코드로 구현한다.
function loadToDos() {
const loadedToDos = localStorage.getItem(TODOS_LS);
if (loadedToDos !== null) {
const parsedToDos = JSON.parse(loadedToDos);
parsedToDos.forEach(function (toDo) {
// parsedToDos에 들어있는 각 데이터를 toDo라는 매개변수에 넣어서 아래 명령문을 실행힌다.
paintToDo(toDo.text);
})
}
}
[출력화면]
5. 전체코드
const toDoForm = document.querySelector(".js-toDoForm");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.querySelector(".js-toDoList");
const TODOS_LS = 'toDos';
const toDos = []; // toDo를 저장할 리스트 생성
function saveToDos() { // 저장할 때, object를 string으로 형변환
// JSON.stringify()를 이용하면 object를 string으로 형변환할 수 있다.
localStorage.setItem(TODOS_LS, JSON.stringify(toDos));
}
function paintToDo(text) {
const li = document.createElement("li"); // li 생성(엘리먼트를 생성시키는 함수 )
const delBtn = document.createElement("button"); //버튼 생성
const span = document.createElement("span");
const newId = toDos.length + 1;
delBtn.innerText = "❌";
span.innerText = text;
li.appendChild(span); // li 태그 내부에 자식태그를 생성하는 함수
li.appendChild(delBtn);
toDoList.appendChild(li);
li.id = newId; // li태그를 삭제할 때, 어떤 li태그를 삭제할 것인지 구분하기 위해 id속성값을 부여
const toDoObj = { // toDos 배열안에 넣을 정보를 setup
text: text,
id: newId
};
toDos.push(toDoObj); // setup된 정보를 배열에 push
saveToDos(); // toDos를 지역저장소에 저장하는 함수를 호출
}
function handleSubmit(event) {
event.preventDefault();
const currentValue = toDoInput.value;
paintToDo(currentValue);
toDoInput.value = "";
}
function loadToDos() {
const loadedToDos = localStorage.getItem(TODOS_LS);
if (loadedToDos !== null) {
const parsedToDos = JSON.parse(loadedToDos);
// 스트링으로 바뀌어 저장되어있는 value를 불러와서 사용해야 하므로
// JSON을 활용하여 string을 다시 object로 형변환 시켜준다.
parsedToDos.forEach(function (toDo) {
// parsedToDos에 들어있는 각 데이터를 toDo라는 매개변수에 넣어서 아래 명령문을 실행힌다.
paintToDo(toDo.text);
})
}
}
function init() {
loadToDos();
toDoForm.addEventListener("submit", handleSubmit);
}
init();
'Front-end > Vanilla JS' 카테고리의 다른 글
JS 근본공부 - 자바스크립트의 역사 (0) | 2020.10.23 |
---|---|
Vanilla JS - 지역저장소를 이용해서 toDoList 만들기(2) (0) | 2020.10.16 |
Vanilla JS - 지역 저장소(Local Storage) (0) | 2020.10.10 |
Vanilla JS - 시계 만들기 (0) | 2020.10.10 |
Vanilla JS - 조건문(if~else) (0) | 2020.10.08 |
댓글