[자바스크립트 스터디]Review - 바닐라JS로 크롬 앱 만들기(momentum clone) - toDo.js(투두리스트 받기)

문세미·2020년 4월 27일
0
post-thumbnail

toDo.js - 투두리스트 받기 !

👉 html 코드

<form class="js-toDoForm">
     <input type="text" placeholder="Write a to do!"/>
</form>
<ul class="js-toDoList"></ul>

👉 js 코드

const toDoForm = document.querySelector(".js-toDoForm"),
toDoInput = toDoForm.querySelector("input"),
toDoList = document.querySelector(".js-toDoList");

const TODOS_LS = "toDos";
let toDos = [];

function deleteToDo(e){
    const btn = e.target;
    const li = btn.parentNode;
    toDoList.removeChild(li);
    const cleanToDos = toDos.filter(function(toDo){
        return toDo.id !== parseInt(li.id);
    });
    toDos = cleanToDos;
    saveToDos();
}; 

function saveToDos(){
    localStorage.setItem(TODOS_LS, JSON.stringify(toDos));
};

function paintToDo(text){
    const li = document.createElement("li");
    const delBtn = document.createElement("button");
    delBtn.innerText = "❌";
    delBtn.addEventListener("click", deleteToDo);
    const span = document.createElement("span");
    const newId = toDos.length + 1;
    span.innerText = text;
    li.appendChild(span);
    li.appendChild(delBtn);
    li.id = newId;
    // toDoList.appendChild(li); 
    // 원페이지에 스크롤 보이지 않게 하기 위해 숫자 제한 : 8개
    if(newId < 9){
        toDoList.appendChild(li);
    }else{
        alert("최대 8개까지 작성할 수 있습니다!")
    }
    const toDoObj = {
        text: text,
        id: newId
    };
    // toDos.push(toDoObj);
    // 원페이지에 스크롤 보이지 않게 하기 위해 숫자 제한 : 8개
    if(newId < 9){
        toDos.push(toDoObj);
    }
    saveToDos();
};

function handleSubmit(e){
    e.preventDefault();
    const currentValue = toDoInput.value;
    paintToDo(currentValue);
    // 엔터 누르면 input 안 초기화
    toDoInput.value = "";
};

function loadToDos(){
    const loadedToDos = localStorage.getItem(TODOS_LS);
    if(loadedToDos !== null){
        const parsedToDos = JSON.parse(loadedToDos);
        parsedToDos.forEach(function(toDo){
            paintToDo(toDo.text);
        });
    }
};

function init(){
    loadToDos();
    toDoForm.addEventListener("submit",handleSubmit);
};

init();

👉 내가 코드를 작성한 순서

  1. 사용 할 객체를 변수로 선언한다.

  2. init 함수를 만든다.

function init(){

};

init()
  1. 작동함수들을 만든다.

    사용자가 input창에 아직 아무것도 입력하지 않았다면! "js-toDoForm"이 보여진다.

✍ loadToDos()

function loadToDos(){
    const loadedToDos = localStorage.getItem(TODOS_LS);
    if(loadedToDos !== null){
        const parsedToDos = JSON.parse(loadedToDos);
        parsedToDos.forEach(function(toDo){
            paintToDo(toDo.text);
        });
    }
};

localStorage의 TODOS_LS = toDos라는 key값의 value값을 불러온다.
문자열인 그 값을 객체로 변환한다.

JON.parse : 문자열 -> 객체로 변환

JSON 문자열의 구문을 분석하고, 그 결과에서 JavaScript 값이나 객체를 생성한다. <-> JON.stringify와 반대되는 개념!

ex) JSON.parse('null');  // null

문자열 "null" -> null로 변환

forEach : forEach() 메서드는 주어진 함수를 배열 요소 각각에 대해 실행한다.

parsedToDos.forEach(function(toDo){
    paintToDo(toDo.text);
});

객체로 변환 된 value값들을 forEach함수를 사용하여

✍ paintToDo()

function paintToDo(text){
    const li = document.createElement("li");
    const delBtn = document.createElement("button");
    delBtn.innerText = "❌";
    delBtn.addEventListener("click", deleteToDo);
    const span = document.createElement("span");
    const newId = toDos.length + 1;
    span.innerText = text;
    li.appendChild(span);
    li.appendChild(delBtn);
    li.id = newId;
    // toDoList.appendChild(li); 
    // 원페이지에 스크롤 보이지 않게 하기 위해 숫자 제한 : 8개
    if(newId < 9){
        toDoList.appendChild(li);
    }else{
        alert("최대 8개까지 작성할 수 있습니다!")
    }
    const toDoObj = {
        text: text,
        id: newId
    };
    // toDos.push(toDoObj);
    // 원페이지에 스크롤 보이지 않게 하기 위해 숫자 제한 : 8개
    if(newId < 9){
        toDos.push(toDoObj);
    }
    saveToDos();
};

👆 createElement() : 문서에 HTML요소를 추가한다.

createElement(tagName)
ex) const li = document.createElement("li");

👆 createTextNode() : 선택한 요소에 텍스트를 추가한다.

createTextNode( '문자열 입력' )

👆 appendChild() : 선택한 요소 안에 자식 요소를 추가한다.

appendChild(aChild)
ex) toDoList.appendChild(li); 

👆 push() <-> pop()

const array1 = [1, 2, 3];

push() : 배열의 마지막부터 요소로 추가

array1.push(4, 5)
// expected output: Array [1, 2, 3, 4, 5]

pop() : 배열의 마지막 요소를 제거

array1.pop()
// expected output: Array [1, 2]

👆 shift() <-> unshift()

const array1 = [1, 2, 3];
  • shift() : 배열의 첫번째 요소를 제거
array1.shift()
// expected output: Array [2, 3]
  • unshift() : 배열의 첫번째부터 요소로 추가
array1.unshift(4, 5)
// expected output: Array [4, 5, 1, 2, 3]

  1. 객체를 만들고
const toDoObj = {
     text: text,
     id: newId
};
  1. 배열 안에 객체를 push!
toDos = []
toDos.push(toDoObj);

localStorage에도 저장해야하니까
✍ saveToDos()

function saveToDos(){
    localStorage.setItem(TODOS_LS, JSON.stringify(toDos));
};

JON.stringify : 객체 -> 문자열로 변환

JSON(JavaScript Object Notation)
local storage에는 자바스크립트의 data를 저장할 수 없다.
string(문자열)으로만 저장이 가능하다. 그래서 object를 string으로 바꿔줘야 한다 !
<-> JON.parse 반대되는 개념!

사용자가 input창에 todoList를 입력해서 엔터를 누르면!

✍ handleSubmit()

function handleSubmit(e){
    // 새로고침 방지코드
    e.preventDefault();
    const currentValue = toDoInput.value;
    paintToDo(currentValue);
    
    // 엔터 누르면 input안 초기화
    toDoInput.value = "";
};

사용자가 todoList의 delete버튼을 입력하면!
✍ deleteToDo()

function deleteToDo(e){
    const btn = e.target;
    const li = btn.parentNode;
    toDoList.removeChild(li);
    const cleanToDos = toDos.filter(function(toDo){
        return toDo.id !== parseInt(li.id);
    });
    toDos = cleanToDos;
    saveToDos();
}; 

👆 e.target : 특정 이벤트를 트리거 한 요소를 가져온다.
내가 쉽게 이해하기로는 제이쿼리의 this를 생각해보았다! => 여러 btn 중 내가 누른 btn!

👆 parentNode : 현재 노드의 부모를 가리킨다.

👆 filter() : 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환한다.

  1. delBtn을 클릭할 때 -> 해당하는 투두리스트의 li가 html상 사라지고
toDoList.removeChild(li);
  1. html상사라진 li의 id값을 가진 데이터를 filter함수로 인해 localStorage에 새로운 배열로 반환한다.
// const cleanToDos = toDos.filter(function(toDo){
//     return toDo.id !== parseInt(li.id);
// });
// 화살표함수로 표현!
 const cleanToDos = toDos.filter((toDo) => {
        return toDo.id !== parseInt(li.id);
});

👆 화살표함수 : function 표현에 비해 구문이 짧고 자신의 this, arguments, super 또는 new.target을 바인딩 하지 않는다. 화살표 함수는 항상 익명! 함수 표현은 메소드 함수가 아닌 곳에 가장 적합하다. 그래서 생성자로서는 사용할 수 없다.

(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
// 다음과 동일함: => { return expression; }

매개변수가 하나뿐인 경우 괄호는 선택사항:
(singleParam) => { statements }
singleParam => { statements }

매개변수가 없는 함수는 괄호가 필요:
() => { statements }

👆 parseInt : 문자열 -> 정수로 반환한다.

parseInt(string)

ex) parseInt("42") -> 문자열 "42"를 정수 42로 반환한다. = "null" => null

profile
백엔드와 프론트엔드를 사랑하는 현 마크업개발자(퍼블리셔)입니다 :) 자바스크립트, React, Python을 공부하고 있습니다.

0개의 댓글