Js Challenge14 - #7 Memo App

가짜 개발자·2023년 2월 8일
0

JS Challenge14

목록 보기
8/15
post-thumbnail

crud는 어떤 서비스를 만들때 필수적으로 들어간다. 그래서 오늘은 메모앱을 만들어 보았다. 얼핏보면 투두리스트와 비슷하다.


✅ Goal

  • CRUD 메모 앱을 구현하다.
  • 로컬스토리지에 나의 메모를 저장한다.

✅ Keyword

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


🟢 create memo

우선 로컬스토리지에 저장된 메모를 가져오기 위한 로직을 작성하였다. 로컬에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));
}

🟢 delete memo

삭제는 의외로 간단하다. remove() 메서드를를 활용하여 삭제후 다시 업데이트 하였다. remove()메서드는 DOM에서 요소를 제거한다.

//...
 deleteBtn.addEventListener("click", () => {
    memo.remove();
    updateMemo();
  });

🟢 Edit 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" : ""}">
      `;
  }
//...

  // 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 = "수정";
    }
  });



✅ 기능 시연 및 코드

이번 첼린지는 나름 재미있게 하였다. 또 한 로컬스토리지를 통해 새로고침을 하여도 데이터 값들이 초기화 되지 않는 다는 점에서 매력을 느꼈다. 나중에 더 깊게 공부해서 로그인과 관련하여 토큰 값들을 저장해보는 시간도 가져야 겠다.

🟢 memo 생성

🟢 memo 삭제

🟢 memo 수정

🟢 memo localStorage


🟢 js code

// 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
배포링크

profile
프론트 개발 일지

0개의 댓글