바닐라js로 크롬 앱 만들기(노마드 코더)-3

TO-DO-LIST

todo.js 파일 생성, html에서 임포트 -

todo를 작성할 form을 만들자 --

그리고 todo가 나타날 빈 리스트를 만들자(채워넣는 건 자바스크립트 파일에서.)--

    자바스크립트 파일에서 html의 form들을 가져오기 --
    const toDoForm = document.getElementById("todo-form");
    const toDoInput = toDoForm.querySelector("input");
    const toDoList = document.getElementById("todo-list");

    할일 목록을 엔터 쳐도 리로드가 되지 않도록 하기.--
    function handleToDoSubmit(event) { event.preventDefault();}
    toDoForm.addEventListener("submit", handleToDoSubmit);

    엔터 칠떄마다 할일 칸을 비우고, 입력한 할일을 저장하기.--
    엔터칠떄마다 빈값 입력-- toDoInput.value="";
    입력된 값을 변수로 저장. -- const newTodo = toDoInput.value;

    이제 입력된 할일을 표현해 보도록하자, 문서에다가

  • 할일
  • 이런 방식으로 기술하고 싶다. 그에 맞는 함수를 작성해보자.
    function paintToDo(newTodo){
        const li = document.createElement("li");
        const span = document.createElement("span");
        li.appendChild(span);
        span.innerText = newTodo;
        toDoList.appendChild(li);
    }


    이렇게 입력된 할일이 나타난다.
    그러나 새로고침 하면 전부 사라지므로 이것도 고쳐야 한다.

    할일을 삭제하는 버튼 생성 --

    const button = document.createElement("button");
    button.innerText = "❌";
    button.addEventListener("click", deleteToDo);

    삭제 기능 함수 --
    function deleteToDo(event) {
    const li = event.target.parentElement;
    li.remove();
    }
    여기서 event는 버튼의 인자, 즉 이벤트의 타겟의 부모 요소는 버튼이 속해있는 li 를 가리키며, li에는 할일이 표시 되 있으므로 이를 없애주게 된다.

    할일을 저장하기

    새로고침해도 안지워지도록 저장소에 저장 해보자.

    저장할 배열을 만들기 --const toDos = [];
    배열에다가 할일을 저장 -- toDos.push(newTodo);

    로컬 스토리지에는 배열을 저장할 수 없고 오로지 텍스트만 저장할 수 있다.
    그래서 필요한 게 JSON.stringify, 안에 들어간 걸 문자열(string)로 바꿔줌.

    저장하는 함수 --
    function saveToDos(){
    localStorage.setItem("todos", JSON.stringify(toDos));
    }

    저장을 실행하기 -- saveToDos();

    https://mkil.tistory.com/322
    JSON.stringify가 문자열로 변환해 준다면 parse는 그 정반대의 역할을 한다.

    저장된 할일 정보를 가져오기 --const savedToDos = localStorage.getItem(TODOS_KEY);
    정보가 json형태이므로 이를 코드에서 쓰기 위해서 parse를 사용. --
    if (savedToDos !== null) {
    const parsedToDos = JSON.parse(savedToDos);
    parsedToDos.forEach((item) => console.log("this is the turn of ", item));
    }

    자바스크립트는 배열에 있는 각각의 (foreach) 아이템(item)들에 대해서 function을 실행할 수 있게 해준다

    이제 저장된 할일을 지울때, 화면에서만 지워지는 게 아니라 저장소 자체에서 지워지도록 해보자.

    배열을 불변이 아닌 가변의 let으로 바꾸기 -- let toDos = [];

    id와 텍스트가 있는 할일 객체를 생성 --
    const newTodoObj = {
    text: newTodo,
    id: Date.now(),
    };
    이 객체를 사용해서 전달하기 --
    toDos.push(newTodoObj);
    paintToDo(newTodoObj);

    이로써 let toDos = [];배열에 들어가는 건 단순한 값이 아닌 객체가 된다.
    (Date.now()는 밀리초 단위의 랜덤값을 준다.)

    만약 저장소에 할일 정보가 있으면 정보를 전달 -- toDos = parsedToDos;

    객체가 가진 두개의 값, id와 텍스트 값을 전달.--
    li.id = newTodo.id;
    span.innerText = newTodo.text;

    중요한 점은. 저장소의 할일 정보를 없앤다고 해서 그게 실제로 배열에서 값을 지우는 게 아니라.
    그 값이 제외된 새로운 배열을 생성하는 것이란 거다.

    더알아보기 --

    forEach와 비슷한 역할을 하는 filter에 대해서.

    [1,2,3,4].filter(clean)
    필터는 인자로 들어간 clean함수를 배열의 각각의 item들, 1,2,3,4에 대해서 실행 한다.이때에 clean은 각각의 아이템을 인자로 받아 실행됨(clean(1),clean(2)...)
    clean함수는 무조건 참의 값을 리턴해야만 한다. 만약 거짓이 나오면 그 값은 배열에 포함되지 않는다.

    예) 3에서 거짓이 나오면

    clean(1) =1
    clean(2) =2
    clean(3) x
    clean(4) =4

    clean(3)의 값이 배열에 포함되지 않는다.

    예)
    const arr=["피자","바나나","토마토"]
    function clean(food){ return food !== "바나나"}
    arr.filter(clean)
    결과 : (2) ['피자', '토마토']

    즉 filter는 말그대로 함수라는 기준을 사용한 거름망의 역할을 하는 것이다.

    =>를 쓰면 한줄 짜리 함수를 간단하게 만들 수 있다.
    아래의 두 함수는 서로 같은 기능이다.

    // 함수 표현
    filteredArray = myArray.filter(function(element){
    return element > 2;
    });

    // 화살표 함수
    filteredArray = myArray.filter(element => element > 2);

    이제 필터를 사용해서 할일 삭제시, 아이디를 서로 매칭해서, 그 아이디와 맞는 값을 저장소에서 제외하고 새로운 배열을 생성해 저장하도록 하자.--
    toDos = toDos.filter((toDo) => toDo.id !== parseInt(li.id));
    saveToDos()

    그럼 이렇게 todo리스트가 완성된다.

    날씨 위젯 만들기

    weather.js 파일 생성.

    user의 위치 (geolocation)를 주는 함수 사용.--
    navigator.geolocation.getCurrentPosition(onGeoOk, onGeoError);
    두개의 인자를 받는데 데이터를 받는데 성공시의 함수, 실패시의 함수를 받는다.

    일단 함수 실행시

    이렇게 확인 창이 뜬다.

    성공시 함수 --
    function onGeoOk(position) {
    const lat = position.coords.latitude;
    const lng = position.coords.longitude;
    console.log("You live in", lat, lng);
    }
    위도, 경도를 변수로 가져오자.

    실패시 --
    function onGeoError() {
    alert("잘 못찾겠어요.");
    }

    날씨 정보를 가져올 수 있는 사이트
    https://openweathermap.org/api
    사용 --https://namjackson.tistory.com/27

    html 파일에 날씨 표시창 생성

    <div id="weather">
        <span></span>
        <span></span>
      </div>

    api를 써서 날씨 표현하기

    const weather = document.querySelector("#weather span:first-child");
    const city = document.querySelector("#weather span:last-child");
    const API_KEY = "241051bf13976dd3ddf8b8d9f247255e";
    
    function onGeoOk(position) {
      const lat = position.coords.latitude;
      const lon = position.coords.longitude;
      const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`;
      fetch(url)
        .then((response) => response.json())
        .then((data) => {
          city.innerText = data.name;
          weather.innerText = `${data.weather[0].main} / ${data.main.temp}`;
        });
    }
    function onGeoError() {
      alert("Can't find you. No weather for you.");
    }
    navigator.geolocation.getCurrentPosition(onGeoOk, onGeoError);

좋은 웹페이지 즐겨찾기