crud는 어떤 서비스를 만들때 필수적으로 들어간다. 그래서 오늘은 메모앱을 만들어 보았다. 얼핏보면 투두리스트와 비슷하다.
localStorage.getItem
localStorage.setItem
이번에 중요하게 여길 키워드는 로컬스토리지 저장이다.
localStorage 읽기 전용 속성을 사용하면 Document 출처의 Storage 객체에 접근할 수 있다.
저장한 데이터는 브라우저 세션 간에 공유된다. localStorage는 sessionStorage와 비슷하지만, localStorage의 데이터는 만료되지 않고 sessionStorage의 데이터는 페이지 세션이 끝날 때, 즉 페이지를 닫을 때 사라지는 점이 다르다.
// 항목 추가
localStorage.setItem('myCat', 'Tom');
// 읽기 및 가져오기
const cat = localStorage.getItem('myCat');
// 제거
localStorage.removeItem('myCat');
// 전체제거
localStorage.clear();
로컬스토리지는 유용하게 사용되니 익혀두자.
https://developer.mozilla.org/ko/docs/Web/API/Window/localStorage
우선 로컬스토리지에 저장된 메모를 가져오기 위한 로직을 작성하였다. 로컬에memos
키값이 있다면 저장된 메모가 나오도록 하였다.
//...
const memos = JSON.parse(localStorage.getItem("memos"));
if (memos) {
memos.forEach((memo) => addNewMemo(memo));
}
또한 메모 업데이트함수를 만들어서 메모를 생성할때마다 로컬에memos
키에 값들을 저장하였다.
//....
textArea.addEventListener("input", (e) => {
const { value } = e.target;
memoText.innerText = value;
updateMemo();
});
memoList.appendChild(memo);
}
function updateMemo() {
const memoText = document.querySelectorAll("textarea");
const memos = [];
memoText.forEach((memo) => memos.push(memo.value));
localStorage.setItem("memos", JSON.stringify(memos));
}
삭제는 의외로 간단하다. remove()
메서드를를 활용하여 삭제후 다시 업데이트 하였다. remove()
메서드는 DOM에서 요소를 제거한다.
//...
deleteBtn.addEventListener("click", () => {
memo.remove();
updateMemo();
});
수정하기 부분은 버튼 클릭시 수정모드에 들어가야 하기 떄문에 조금 까다로웠다. 이부분은 조건문을 활용하여 구현하였다.
//...
if (text === "") {
memo.innerHTML = `
<div class="btnWrapper">
<button class="edit">저장</button>
<button class="delete">삭제</button>
</div>
<div class="text ${text ? "" : "hide"}"></div>
<textarea class="${text ? "hide" : ""}">
`;
} else if (memos) {
memo.innerHTML = `
<div class="btnWrapper">
<button class="edit">수정</button>
<button class="delete">삭제</button>
</div>
<div class="text ${text ? "" : "hide"}"></div>
<textarea class="${text ? "hide" : ""}">
`;
}
//...
// edit btn
editBtn.addEventListener("click", (e) => {
if (e.target.innerText === "수정") {
memoText.classList.add("hide");
textArea.classList.remove("hide");
editBtn.innerText = "저장";
} else if (e.target.innerText === "저장") {
memoText.classList.remove("hide");
textArea.classList.add("hide");
editBtn.innerText = "수정";
}
});
이번 첼린지는 나름 재미있게 하였다. 또 한 로컬스토리지를 통해 새로고침을 하여도 데이터 값들이 초기화 되지 않는 다는 점에서 매력을 느꼈다. 나중에 더 깊게 공부해서 로그인과 관련하여 토큰 값들을 저장해보는 시간도 가져야 겠다.
// index.js
const container = document.getElementById("container");
const addMeomoBtn = document.createElement("button");
const memoList = document.createElement("div");
addMeomoBtn.innerText = "add Memo";
addMeomoBtn.className = "addBtn";
container.appendChild(addMeomoBtn);
container.appendChild(memoList);
memoList.className = "memolist";
const memos = JSON.parse(localStorage.getItem("memos"));
if (memos) {
memos.forEach((memo) => addNewMemo(memo));
}
addMeomoBtn.addEventListener("click", () => addNewMemo());
function addNewMemo(text = "") {
const memo = document.createElement("div");
memo.classList.add("memo");
if (text === "") {
memo.innerHTML = `
<div class="btnWrapper">
<button class="edit">저장</button>
<button class="delete">삭제</button>
</div>
<div class="text ${text ? "" : "hide"}"></div>
<textarea class="${text ? "hide" : ""}">
`;
} else if (memos) {
memo.innerHTML = `
<div class="btnWrapper">
<button class="edit">수정</button>
<button class="delete">삭제</button>
</div>
<div class="text ${text ? "" : "hide"}"></div>
<textarea class="${text ? "hide" : ""}">
`;
}
const deleteBtn = memo.querySelector(".delete");
const editBtn = memo.querySelector(".edit");
const memoText = memo.querySelector(".text");
const textArea = memo.querySelector("textarea");
textArea.value = text;
memoText.innerText = text;
// delete btn
deleteBtn.addEventListener("click", () => {
memo.remove();
updateMemo();
});
// edit btn
editBtn.addEventListener("click", (e) => {
if (e.target.innerText === "수정") {
memoText.classList.add("hide");
textArea.classList.remove("hide");
editBtn.innerText = "저장";
} else if (e.target.innerText === "저장") {
memoText.classList.remove("hide");
textArea.classList.add("hide");
editBtn.innerText = "수정";
}
});
// create
textArea.addEventListener("input", (e) => {
const { value } = e.target;
memoText.innerText = value;
updateMemo();
});
memoList.appendChild(memo);
}
// localupdate
function updateMemo() {
const memoText = document.querySelectorAll("textarea");
const memos = [];
memoText.forEach((memo) => memos.push(memo.value));
localStorage.setItem("memos", JSON.stringify(memos));
}
https://github.com/fake-dp/Js-Challenge14-Mini-Project/tree/main/MemoApp
배포링크