프론트엔드 공부/Javascript 기초

29일차 프론트엔드 공부

프망생222 2024. 10. 13. 11:03

- 프론트엔드 공부 29일차 -


구조분해할당

구조화 되어 있는 배열, 객체와 같은 데이터를 destructuring(분해) 시켜, 각각의 변수에 담는 것

 

let arr = [1, 2]

let [one, two] = arr

console.log(one, two) // 1 2

 

let obj = { name: "otter", gender: "male" } 

let { name, gender } = obj

console.log(name, gender) // otter male

 

let { name: newName, gender: newGender } = obj

console.log(newName) // otter

 

spread 연산자

하나로 뭉쳐있는 값들의 집합을 전개해주는 연산자

 

const arr = [ 1, 2, 3, 4, 5 ];

console.log(arr)    // [1, 2, 3, 4, 5]

console.log(...arr) // 1, 2, 3, 4, 5

 

let str = “Hello”

console.log(str)     // “Hello”

console.log(...str) //  “H” “e” “l” “l” “o”

 

얕은 복사, 깊은 복사

주소값까지만 복사하는 얕은 복사

실제 데이터까지 복사하는 깊은 복사

 

let origin = {

name : “otter”

age: 25

};

 

let copy = origin

origin.name // “otter”

copy.name = “rabbit”

origin.name // “rabbit”

 

얕은 복사

let origin = {

name : “otter”

age: 25

};

let copy = {

name : origin.name

age: origin.age

};

 

origin.name // “otter”

copy.name = “rabbit”

origin.name // “otter”

 

매번 각각의 값을 복사

 

스프레드 연산자

let origin = {

name : “otter”

age: 25

};

let copy = {...origin}

copy // {name: “otter”, age: 25}

 

let arr = [1, 2, 3, 4, 5]

let secArr = [6, 7, 8]

let copy = [...arr, …secArr ]

copy // [1, 2, 3, 4, 5, 6, 7, 8]



깊은 복사

let origin = {

name : “otter”

age: 25

favoriteFood:{

first: “sushi”

second: “hamburger”

}

};

 

const copy = {...origin }

 

copy.favoriteFood.first = “cold noodle”

origin.favoriteFood //{first: “cold noodle”, second: “hamburger”}



const copy = JSON.stringify(origin)

copy // {“name” : “otter”, age”: 25, “favoriteFood”:{“first”: “sushi”, “second”: “hamburger”}};

const deepCopy = JSON.parse(copy)

deepCopy // {

name : “otter”

age: 25

favoriteFood:{

first: “sushi”

second: “hamburger”

}

};


Rest Parameter

let origin = {

name : “otter”

age: 25

petName: “cherry”

hobby: “game”

};

 

const{ petName, hobby, …rest } = origin

petName // cherry

hobby  // game

rest // {name: “otter”, age: 25 }

 

 

내위치의 주소를 가져와서 배경에 현재 날씨를 출력해주는 TodoList 사이트 만들기

 

HTML

<!DOCTYPE html>
<html lang="ko">
  <head>
    <title>오늘 할일</title>
    <link rel="stylesheet" href="./index.css" />
    <script src="./index.js" defer></script>
  </head>
  <body>
    <h1 id="locationName">ToDo</h1>
    <div class="todoContainer">
      <input type="text" id="todoInput" onkeydown="keyCodeCheck()" />
      <ul id="todoList"></ul>
    </div>
    <div class="deleteBtnWrapper">
      <button onclick="deleteAll()">전체 삭제</button>
    </div>
  </body>
</html>

 

CSS

* {
  box-sizing: border-box;
}

body {
  background-image: url("./images/Clear.jpg");
  background-size: cover;
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 0;
  min-height: 100vh;
}

h1 {
  color: white;
  text-shadow: 2px 2px gray;
  opacity: 85%;
}

input {
  opacity: 80%;
}

.todoContainer {
  max-width: 100%;
  width: 400px;
}

#todoInput {
  background-color: lightyellow;
  border: none;
  display: block;
  font-size: 2rem;
  padding: 0.5rem 2rem 0.5rem 0.5rem;
  width: 100%;
}

#todoList {
  background-color: lightyellow;
  list-style-type: none;
  margin: 0;
  padding: 0;
}

#todoList li {
  border-top: 1px solid rgb(242, 242, 242);
  font-size: 1.5rem;
  user-select: none;
}

.complete {
  color: rgb(155, 155, 155);
  text-decoration: line-through;
}

li button {
  background-color: mintcream;
  width: 1.5rem;
  height: 1.5rem;
  margin: 0.5rem;
  border: 2px solid black;
  border-radius: 8px;
  cursor: pointer;
}

li button:active {
  border: 2px solid grey;
}

.deleteBtnWrapper {
  margin-top: 1rem;
}

.deleteBtnWrapper button {
  font-weight: bold;
  border: none;
  border-radius: 5px;
  box-shadow: 3px 3px gray;
  background-color: antiquewhite;
  padding: 0.2rem 1rem;
  cursor: pointer;
}

.deleteBtnWrapper button:active {
  box-shadow: none;
  margin-left: 3px;
  margin-top: 3px;
}

 

JS

const todoInput = document.querySelector("#todoInput");
const todoList = document.querySelector("#todoList");

const savedTodoList = JSON.parse(localStorage.getItem("save-Items"));

const savedWeatherData = JSON.parse(localStorage.getItem("saved-weather"));

const createTodo = function (storageData) {
  let todoContents = todoInput.value;
  if (storageData) {
    todoContents = storageData.contents;
  }

  const newLi = document.createElement("li");
  const newSpan = document.createElement("span");
  const newBtn = document.createElement("button");

  newBtn.addEventListener("click", () => {
    newLi.classList.toggle("complete");
    saveItem();
  });

  newLi.addEventListener("dblclick", () => {
    newLi.remove();
    saveItem();
  });

  if (storageData?.complete === true) {
    newLi.classList.add("complete");
  }

  newSpan.textContent = todoContents;
  newLi.appendChild(newBtn);
  newLi.appendChild(newSpan);
  todoList.appendChild(newLi);
  todoInput.value = "";
  saveItem();
};

const keyCodeCheck = function () {
  if (window.event.keyCode === 13 && todoInput.value.trim() !== "") {
    createTodo();
  }
};

const deleteAll = function () {
  const liList = document.querySelectorAll("li");
  for (let i = 0; i < liList.length; i++) {
    liList[i].remove();
  }
  saveItem();
};

const saveItem = function () {
  const saveItems = [];
  for (let i = 0; i < todoList.children.length; i++) {
    const toDoObj = {
      contents: todoList.children[i].querySelector("span").textContent,
      complete: todoList.children[i].classList.contains("complete"),
    };
    saveItems.push(toDoObj);
  }
  if (saveItems.length === 0) {
    localStorage.removeItem("save-Items");
  } else {
    localStorage.setItem("save-Items", JSON.stringify(saveItems));
  }
};

if (savedTodoList) {
  for (let i = 0; i < savedTodoList.length; i++) {
    createTodo(savedTodoList[i]);
  }
}

const weatherDataActive = function ({ location, weather }) {
  const weatherMainList = [
    "Clear",
    "Clouds",
    "Drizzle",
    "Rain",
    "Snow",
    "Thunderstorm",
  ];
  weather = weatherMainList.includes(weather) ? weather : "fog";

  const locationName = document.querySelector("#locationName");
  locationName.textContent = location;
  document.body.style.backgroundImage = `url('./images/${weather}.jpg')`;

  if (
    !savedWeatherData ||
    savedWeatherData.location !== location ||
    savedWeatherData.weather !== weather
  ) {
    localStorage.setItem(
      "saved-weather",
      JSON.stringify({ location, weather })
    );
  }
};

const weatherSearch = function ({ latitude, longitude }) {
  const openWeatherResponse = fetch(
    `https://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=39c7d755519bce2f67d19d066b5425f0`
  )
    .then((res) => {
      return res.json();
    })
    .then((json) => {
      const weatherData = {
        location: json.name,
        weather: json.weather[0].main,
      };
      weatherDataActive(weatherData);
    })
    .catch((err) => {
      console.error(err);
    });
};

const accessToGeo = function ({ coords }) {
  const { latitude, longitude } = coords;
  const positionObj = {
    latitude,
    longitude,
  };
  weatherSearch(positionObj);
};

const askForLocation = function () {
  navigator.geolocation.getCurrentPosition(accessToGeo, (error) => {
    console.log(error);
  });
};

askForLocation();

if (savedWeatherData) {
  weatherDataActive(savedWeatherData);
}

 

 

  if (window.event.keyCode === 13 && todoInput.value.trim() !== ""

trim() 이란

입력한 값의 좌우 공백을 제거하는  함수

해당 코드를 입력하면 공백을 입력하는 것을 방지할 수 있다.