Javascript30 - LocalStorage

seeh_h·2021년 1월 30일
1

javascript30

목록 보기
13/16

이번 실습에는 Localstorage를 이용해서 페이지가 refresh 됐을때도 입력했던 값이 사라지지 않고 유지되는 메뉴판을 만들어 보았다.

Learning Point

  • LocalStorage에 대해 학습한다.
  • JSON.stringify, JSON.parse에 대해 학습한다.
  • e.preventDeafult에 대해 학습한다.

HTML Part

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>LocalStorage</title>
    <link rel="stylesheet" href="style.css" />
    <script defer src="index.js"></script>
  </head>
  <body>
    <!--
      Fish SVG Cred:
      https://thenounproject.com/search/?q=fish&i=589236
   -->

    <svg
      xmlns="http://www.w3.org/2000/svg"
      xmlns:xlink="http://www.w3.org/1999/xlink"
      version="1.1"
      x="0px"
      y="0px"
      viewBox="0 0 512 512"
      enable-background="new 0 0 512 512"
      xml:space="preserve"
    >
      <g>
        <path
          d="M495.9,425.3H16.1c-5.2,0-10.1,2.9-12.5,7.6c-2.4,4.7-2.1,10.3,0.9,14.6l39,56.4c2.6,3.8,7,6.1,11.6,6.1h401.7   c4.6,0,9-2.3,11.6-6.1l39-56.4c3-4.3,3.3-9.9,0.9-14.6C506,428.2,501.1,425.3,495.9,425.3z M449.4,481.8H62.6L43,453.6H469   L449.4,481.8z"
        />
        <path
          d="M158.3,122c7.8,0,14.1-6.3,14.1-14.1V43.4c0-7.8-6.3-14.1-14.1-14.1c-7.8,0-14.1,6.3-14.1,14.1v64.5   C144.2,115.7,150.5,122,158.3,122z"
        />
        <path
          d="M245.1,94.7c7.8,0,14.1-6.3,14.1-14.1V16.1c0-7.8-6.3-14.1-14.1-14.1C237.3,2,231,8.3,231,16.1v64.5   C231,88.4,237.3,94.7,245.1,94.7z"
        />
        <path
          d="M331.9,122c7.8,0,14.1-6.3,14.1-14.1V43.4c0-7.8-6.3-14.1-14.1-14.1s-14.1,6.3-14.1,14.1v64.5   C317.8,115.7,324.1,122,331.9,122z"
        />
        <path
          d="M9.6,385.2c5.3,2.8,11.8,1.9,16.2-2.2l50.6-47.7c56.7,46.5,126.6,71.9,198.3,71.9c0,0,0,0,0,0   c87.5,0,169.7-36.6,231.4-103.2c5-5.4,5-13.8,0-19.2c-61.8-66.5-144-103.2-231.4-103.2c-72,0-142.2,25.6-199,72.5l-50-47.1   c-4.4-4.1-10.9-5-16.2-2.2c-5.3,2.8-8.3,8.7-7.4,14.6l11.6,75L2.2,370.6C1.3,376.5,4.2,382.4,9.6,385.2z M380.9,230.8   c34.9,14.3,67.2,35.7,95.3,63.6c-10.1,10-20.8,19.2-31.9,27.5c-22.4-3.3-29.6-8.8-30.7-9.7c-4-5.7-11.8-7.7-18.1-4.4   c-6.9,3.6-9.5,12.2-5.9,19.1c1.9,3.5,7.3,10.3,22.4,16c-10.1,5.7-20.5,10.7-31.1,15.1C352.4,320.2,352.4,268.6,380.9,230.8z    M36.3,255.6l29.4,27.7c5.3,5,13.6,5.1,19.1,0.3c53.2-47.6,120.7-73.7,190-73.7c26.9,0,53.2,3.9,78.5,11.3   c-29.3,44.6-29.3,102,0,146.6c-25.3,7.4-51.6,11.3-78.5,11.3c-69,0-136.3-26-189.4-73.2c-2.7-2.4-13.4-6.3-19.1,0.3l-30.1,28.3   l5.7-40C42.2,293,36.3,255.6,36.3,255.6z"
        />
        <circle cx="398.8" cy="273.8" r="14.1" />
      </g>
    </svg>

    <div class="wrapper">
      <h2>LOCAL TAPAS</h2>
      <p></p>
      <ul class="plates"></ul>
      <form class="add-items">
        <input type="text" name="item" placeholder="Item Name" required />
        <input type="submit" value="+ Add Item" />
      </form>
    </div>
  </body>
</html>

CSS Part

html {
  box-sizing: border-box;
  background: url("oh-la-la.jpeg") center no-repeat;
  background-size: cover;
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  font-family: Futura, "Trebuchet MS", Arial, sans-serif;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

svg {
  fill: white;
  background: rgba(0, 0, 0, 0.1);
  padding: 20px;
  border-radius: 50%;
  width: 200px;
  margin-bottom: 50px;
}

.wrapper {
  padding: 20px;
  max-width: 350px;
  background: rgba(255, 255, 255, 0.95);
  box-shadow: 0 0 0 10px rgba(0, 0, 0, 0.1);
}

h2 {
  text-align: center;
  margin: 0;
  font-weight: 200;
}

.plates {
  margin: 0;
  padding: 0;
  text-align: left;
  list-style: none;
}

.plates li {
  border-bottom: 1px solid rgba(0, 0, 0, 0.2);
  padding: 10px 0;
  font-weight: 100;
  display: flex;
}

.plates label {
  flex: 1;
  cursor: pointer;
}

.plates input {
  display: none;
}

.plates input + label:before {
  content: "⬜️";
  margin-right: 10px;
}

.plates input:checked + label:before {
  content: "🌮";
}

.add-items {
  margin-top: 20px;
}

.add-items input {
  padding: 10px;
  outline: 0;
  border: 1px solid rgba(0, 0, 0, 0.1);
}

Javascript Part

const addItems = document.querySelector(".add-items");
const itemsList = document.querySelector(".plates");
const plates = document.querySelector(".plates");
const items = JSON.parse(localStorage.getItem("items")) || [];

const addPlate = (plateList) => {
  plates.innerHTML = plateList
    .map((item, i) => {
      return `
      <li>
        <input type="checkbox" data-index=${i} id=item${i} ${
        item.done ? "checked" : ""
      }/>
        <label for="item${i}">${item.name}</label>
      </li>
      `;
    })
    .join("");
};

const handleSubmit = (e) => {
  e.preventDefault();
  const input = document.querySelector("input[name=item]");

  const plate = {
    name: input.value,
    done: false,
  };

  items.push(plate);
  addPlate(items);
  localStorage.setItem("items", JSON.stringify(items));
  addItems.reset();
};

const toggleUpdate = (e) => {
  if (!e.target.matches("input")) return;

  const id = e.target.dataset.index;
  items[id].done = !items[id].done;
  localStorage.setItem("items", JSON.stringify(items));
};

addItems.addEventListener("submit", handleSubmit);
plates.addEventListener("click", toggleUpdate);

addPlate(items);
profile
주니어 개발자 성장기😎

0개의 댓글