Day 15 - LocalStorage, Contains emphasized items

오랜만에 영상을 먼저 보지 않고 혼자 구현할 수 있었던 과제였다. localStorage의 사용법만 안다면 (매우 간단하다) 리스트를 만들어 관리하는 것은 투두리스트를 많이 만들어봤기에 자신있었다.

localStorage의 사용

자바스크립트에서는 기본적으로 로컬 스토리지에, 즉 클라이언트의 로컬 컴퓨터에 어떠한 데이터를 저장, 삭제, 조회할 수 있는 메소드가 있다. 브라우저마다 다르지만, 보통 5MB 정도의 용량을 허용한다고 한다. (사실 5MB 정도면 텍스트 데이터정도를 저장하기에는 충분하다)

저장, 조회, 삭제에 대한 방법만 알면 충분하다.

  • 저장: localStorage.setItem('<item명>', <저장할 item>)
  • 데이터 조회: localStorage.getItem('<item명>')
  • 특정 카테고리 삭제: localStorage.clear('<item명>')
  • 로컬 스토리지 전체 삭제: localStorage.clear()

아이템 새로고침, 추가, 토글 구현

로직은 매우 간단한데, <input>에서 추가할 텍스트 데이터를 items라는 배열에 넣고 로컬 스토리지에 저장 후 리스트에 텍스트 데이터를 하나씩 추가하면 된다. 여기서 중요한 것은, 로컬 스토리지에 저장하기 때문에 굳이 하나씩 넣을 필요도 없고, 배열 전체를 받아 innerHTML로 새로고침하는 함수를 하나 만들면 된다.
(데이터가 많아지면 비효율적이겠지만 간단한 메뉴 리스트이기에 무관하다)

새로고침

우선 배열을 받아 list를 새로고침하는 함수이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function populateList(plates = [], platesList) {
platesList.innerHTML = plates
.map((plate, i) => {
return `
<li>
<input type="checkbox" data-index=${i} id="item${i}" ${
plate.done ? "checked" : ""
} />
<label for="item${i}">${plate.text}</label>
</li>
`;
})
.join("");
}

각 요소를 <li> 태그의 요소로 바꿔 한개씩 join('') 시켜주면 리스트 전체를 원하는 innerHTML로 바꿔주는 함수이다.

이제 리스트를 추가하던, 체크박스를 토글하던 이 함수만 실행하면 새로고침된다.

리스트 추가

1
2
3
4
5
6
7
8
9
10
11
12
function addItem(e) {
e.preventDefault();
const text = this.querySelector('[name="item"]').value;
const item = {
text,
done: false,
};
items.push(item);
populateList(items, itemsList);
localStorage.setItem("items", JSON.stringify(items));
this.reset();
}

<form>에 이벤트를 걸기 때문에 e.preventDefault로 기본 동작을 막는다. (안 막으면 기본 동작인 새로고침이 일어난다)

그리고 아이템의 값을 JSON을 이용하여 String으로 바꿔주고 리스트를 새로고침, 로컬스토리지에도 저장하면 된다.

this.reset()을 하지 않으면 기본 동작을 막아놨기 때문에 폼에 입력한 내용들이 날라가지 않고 그대로 남아있게 되기에 꼭 날려주자.

체크박스 토글

마지막으로 구현할 것은 체크박스 토글이고, 이 역시 로컬스토리지에 변경 내용이 저장되어야 한다.

1
2
3
4
5
6
7
function toggleDone(e) {
if (e.target.type != "checkbox") return;
const index = e.target.dataset.index;
items[index].done = !items[index].done;
localStorage.setItem("items", JSON.stringify(items));
populateList(items, itemsList);
}

items 배열의 done 값을 반대로 저장하고, 로컬스토리지와 새로고침하는 과정은 addItem() 함수의 로직과 같다.

이제 이 모든 함수들을 이벤트만 걸어주면 끝이다.

1
2
3
addItems.addEventListener("submit", addItem);
itemsList.addEventListener("click", toggleDone);
populateList(items, itemsList);

추가 구현 - 전체 삭제

전체 삭제도 만들어보면 좋지 않을까 해서 만든 전체 삭제 함수이다. 당연히 로컬 스토리지도 초기화된다.

먼저 적당한 위치에 버튼을 만들어준다.

1
<input type="button" name="clear" value="Clear all items" />

배운 방법들을 활용하여 초기화 함수를 작성하고 바로 이벤트를 걸어준다.

1
2
3
4
5
document.querySelector('[name="clear"]').addEventListener("click", () => {
localStorage.clear("items");
items.length = 0;
populateList(items, itemsList);
});

items에 해당하는 데이터를 로컬 스토리지에서 모두 날리고, items 배열을 초기화시키는데 이 배열은 const로 선언되었기 때문에 재선언을 할 수 없으므로 length를 0으로 만들어주는 방법이 있다.

이제 30 코스 중 15개를 완수했다. 하루에 1개씩 배우는 재미가 쏠쏠하고, 뿌듯하다.