개인 프로젝트/바닐라 JS로 크롬 앱 만들기

[Nomad Coder] 바닐라 JS로 크롬 앱 만들기 - 파트 2

Jinomad 2020. 7. 15. 20:51

 

 

4. 할 일 리스트 

 

할 일 리스트는 정리하는데 좀 어려웠다. 

로컬 스토리지에 데이터 저장, 요소 삭제, 요소 추가, 화면에 출력, 이벤트 발생시 처리 등 신경쓸게 많았다. 

const toDoForm = document.querySelector(".js-toDoForm"),
toDoInput = toDoForm.querySelector("input"), // input 받은 데이터를 저장한다. 
toDoList = document.querySelector(".js-toDoList"); // 입력 받은 데이터 리스트를 저장한다. 
const TODOS_LS = "toDos";

let toDos = [];

// 리스트를 지운다 
function deleteToDo(event){
  // event의 부모에 대한 정보를 얻을 수 있다.console.log(event.target.parentNode);
  const btn = event.target; // 이벤트의 모든 정보를 반환
  const li = btn.parentNode; // 부모노드의 정보를 반환
  toDoList.removeChild(li); // 'toDoList' 안에서 'li'에 해당하는 요소를 삭제 
  const cleanToDos = toDos.filter(function(toDo){ // true일 경우 원소를 새 배열에 추가
    return toDo.id !== parseInt(li.id); // parseInt : 인트형으로 형변환
  }); // forEach는 무조건 define을 반환, filter는 조건에 만족하는 데이터를 반환 
  toDos = cleanToDos; // cleanToDos(업데이트된 toDOs)를 toDos에 덮어씀 
  saveToDos(); 
}

// LocalStorage에 데이터를 저장한다 
function saveToDos(){
  localStorage.setItem(TODOS_LS, JSON.stringify(toDos));
}

// 리스트를 화면에 출력한다 
function paintToDo(text){
  const li = document.createElement("li"); // 'li' 요소를 만들어 반환
  const delBtn = document.createElement("button"); // 'button' 요소를 만들어 반환
  const span = document.createElement("span"); // 'span' 요소를 만들어 반환
  const newId = toDos.length + 1; // 아이디를 길이 + 1로 지정 
  delBtn.innerText = "❌"; // 삭제버튼 모양 
  delBtn.addEventListener("click", deleteToDo); // 삭제 버튼 클릭시 이벤트 실행
  span.innerText = text; // 입력받은 text값을 span.innerText에 저장 
  li.appendChild(span); // 해당 노드의 자식 노드 리스트의 맨 마지막에 추가
  li.appendChild(delBtn); 
  li.id = newId; // li의 아이디를 추가 
  toDoList.appendChild(li); // 실질적으로 html에 표시되는 toDoList에 정리된 'li'를 자식노드로 추가
  const toDoObj = { // toDo(할일) 데이터 
    text: text,
    id: newId
  };
  toDos.push(toDoObj); // 배열에 할일 정보 삽입
  saveToDos();
}

// 이벤트가 발생할 시 실행
function handleSubmit(event){
  event.preventDefault(); // 현재 이벤트의 기본동작을 중단한다 
  const currentValue = toDoInput.value; // value의 값을 반환한다. 
  paintToDo(currentValue); 
  toDoInput.value = ""; // value를 초기화시킨다. 
}

function loadToDos(){
  const loadedToDos = localStorage.getItem(TODOS_LS); // LocalStorage에서 데이터를 불러옴 
  if (loadedToDos !== null){ // LocalStorage가 null이 아니라면, 즉 기록이 있다면
    const parsedToDos = JSON.parse(loadedToDos); // 인수로 전달받은 문자열을 자바스크립트 객체로 변환하여 반환
    parsedToDos.forEach(function(toDo){ // forEach : array에 있는 것을 한번씩 실행해준다.
      paintToDo(toDo.text);
    });
  }
}

 

 

 

 

5. 그림 백 그라운드 

 

 원하는 사진이나 그림을 웹 페이지의 배경으로 만드는 기능이다.  

const body = document.querySelector("body");
const IMG_NUMBER = 6; // 이미지의 개수 

// 백그라운드를 그린다 
function paintImage(imgNumber){
  const image = new Image(); // 이미지 객체 생성 
  # 이미지의 주소를 '/images/background01~06'로 설정
  image.src = `/images/background${
    (imgNumber+1) < 10 ? `0${imgNumber+1}` : imgNumber+1}.jpg`;
  image.classList.add("bgImage"); // 'bgImage' 클래스를 삽입 
  body.prepend(image); // image를 body 시작부분에 삽입
}

// 랜덤 값을 생성
function genRandom(){
  const number = Math.floor(Math.random() * IMG_NUMBER); // Math.random() : 0~1 사이의 랜덤한 소수값을 반환
  return number; 랜덤으로 0 ~ 5 중 하나를 반환
}

 

우선 랜덤 값을 생성해서 그 랜덤 값을 paintImage에 넘기면,

이미지 객체를 생성하고 랜덤 값에 맞는 이미지 주소를 지정해준다. 그 다음으로 CSS에 쓸 클래스를 삽입해주고 body에 추가해서 적용해주는 것으로 백그라운드를 설정할 수 있다. 

 

해당하는 css는 다음과 같다.

.bgImage{
  position: absolute;
  top:0;
  left:0;
  width:100%; 
  height:100%;
  z-index: -1; // 수직 위치의 우선 순위를 설정. 기본값이 0이기 때문에 -1로하면 맨 뒤로 보낼 수 있다. 
  animation: fadeIn .5s linear;
}

 

 

 

 

6. 현재 날씨 출력 

 

이번엔 API를 이용한 기능인 날씨와 위치 정보를 출력해주는 기능을 구현했다. 

fetch를 이용한 통신과 then으로 데이터를 가공해서 정보를 가져왔다. 

const weather = document.querySelector(".js-weather");

const API_KEY = "API의 KEY 값"; // openweathermap.org에 들어가서 회원가입을하면 자신만의 키 값을 받을 수 있다.
const COORDS = 'coords';

function getWeather(lat, lng){
  // fetch : 사이트와 통신하여 통신에 완료시 then을 실행
  fetch(`https://api.openweathermap.org/data/2.5/weather? 
  lat=${lat}&lon=${lng}&appid=${API_KEY}&units=metric`).then(function(response){
    return response.json(); // JSON으로 바꾸는 결과로 해결되는 promise를 반환한다(??).
  }).then(function(json){
    const temperature = json.main.temp; // 온도(℃)
    const place = json.name; // 장소 
    weather.innerText = `${temperature} @ ${place}`; // 실직적으로 html에 연결된 weather에 결과 반영
  });
}

// LocalStorage에 데이터를 저장한다. 
function saveCoords(coordsObj){
  localStorage.setItem(COORDS, JSON.stringify(coordsObj));
}

// 성공시 발생되는 function 
function handleGeoSucces(position){
  const latitude = position.coords.latitude; // 위도 
  const longitude = position.coords.longitude; // 경도 
  const coordsObj = {
    latitude,
    longitude
  };
  saveCoords(coordsObj);
  getWeather(latitude, longitude);
}

// error 발생 시 실행되는 function 
function handleGeoError(){
  console.log("Can't access geo location");
}

// GPS 요청
function askForCoords(){
  // 첫째 인자는 요청이 성공 했을 때 콜백함수, 둘째 인자는 요청이 실패 했을 때 콜백 함수, 셋째 인자는 수집 옵션
  navigator.geolocation.getCurrentPosition(handleGeoSucces, handleGeoError);
} 

function loadCoords(){
  const loadedCoords = localStorage.getItem(COORDS); // LocalStorage에서 정보를 반환
  if(loadedCoords === null){ // LocalStorage에 저장된 정보가 없다면 
    askForCoords();
  } else{ // 저장된 정보가 있다면 
    const parseCoords = JSON.parse(loadedCoords);
    getWeather(parseCoords.latitude, parseCoords.longitude);
  }
}

 

참고

  - JSON.parse(text) : 문자열을 자바스크립트 객체로 변환

  - JSON.stringify(value) : 자바스크립트 객체를 문자열로 변환

  - Fetch API : 통신에 성공할 경우 then()을 사용하여 콜백함수를 실행합니다. 에러가 발생할 경우 catch()를 이용해서 핸들링합니다. 

 

 


 

마치며.....

처음에는 어려워보였지만 막상 해보니 생각보다 어렵지 않았다. 

 

주로 코드에 주석처리를 하는 방식으로 공부한 것을 정리해봤다

 

이번 강의는 무료 강의라서 부담없이 들을 수 있어서 좋았던 것 같다. 

 

nomadcoders.co/ 

 

Nomad Coders

코딩은 진짜를 만들어보는거야!. 실제 구현되어 있는 서비스를 한땀 한땀 따라 만들면서 코딩을 배우세요.

nomadcoders.co

 

혹시라도 사이트가 어딘지 궁금한 사람들을 위해 주소를 남깁니다.