반응형

1. to-do 리스트 만들기

이렇게 내용을 집어 넣고 엔터를 칠 때 마다 아래에 한줄 한줄 리스트 형식으로 추가되게 해보자

Write a to do 부분 html 이다. 

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

원래 위와같이 input text 밑에 목록을 만드는 <ul> 엄마 태그 아래에 <li> 자식 목록 태그들을 하나씩 

html에 써줘야 저렇게 표시가 될텐데... 내가 동적으로 엔터 칠때마다 저 html 에 

<li ~~~ /> 하나씩 추가가 되어야 한다.. 이걸 자바스크립트로 동적으로 추가해보자?

 

<!DOCTYPE html>
<html>
    <head>
        <title>Something</title>
        <meta charset="utf-8"/>     <!-- 이모지 사용을 위해 사용 -->
        <link rel="stylesheet" href="index.css"/>

    </head>
    <body>
        <!-- 시간 표시 div-->
        <div class="js-clock">
            <h1>00:00</h1>
        </div>

        <!-- 이름 입력하는 폼 -->
        <form class="js-form form">
            <input type="text" placeholder="What is your name?"/>
        </form>

        <!-- hello 사용자 표시하는 제목 태그 -->
        <h4 class="js-greetings greetings"></h4>
        <form class="js-toDoForm">
            <input type="text" placeholder="Write a to do"> 
        </form>
        <ul class="js-toDoList">   
                <!-- 이부분에 li 친구들이 동적 생성 시킬꺼 --> 
        </ul>
        <script src="clock.js"></script>
        <script src="gretting.js"></script> 
        <script src="todo.js"></script> <!-- 추가 -->
    </body>
</html>

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

const TODOS_LS = 'toDos';    

function paintToDo(text) {
    
    // li 태그와 button 태그를 일단 생성해놓는다 
    const li = document.createElement("li");
    const delBtn = document.createElement("button");
    
    // 버튼 안에 들어가는 이모지 내용
    delBtn.innerHTML = "❌";

    // text를 입력할 공간인 span 태그를 생성해놓는다 
    // div 를 사용한다면 텍스트 내용 엔터치고 버튼 이렇게 나와버림
    const span = document.createElement("span");

    // span 안에 입력한 텍스트 내용을 넣고
    span.innerText = text;
    
    // li 리스트 태그에 span + button 을 자식으로 연결해주고
    li.appendChild(span);
    li.appendChild(delBtn);

    // 또 ul (toDoList) 태그 안에 자식을 방금 만든 li 로 연결해주고
    toDoList.appendChild(li);
}

function handleSubmit(event){
    event.preventDefault();
    const currentValue = toDoInput.value;
    paintToDo(currentValue);
    toDoInput.value = "";
}

function loadToDos(){
    const loadedToDos = localStorage.getItem(TODOS_LS);
    if(loadedToDos !== null){
    }
}

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

init();

 스크립트에서 다른 내용은 없다. 전과 같은데 배웠던 class 가져오고 이벤트 연결하고.. 다른건 엘리먼트 추가

 

엘리먼트?

엘리먼트는 완성된 한 문단? <script src="todo.js"></script> 을 엘리먼트라 하고

태그는 그냥 이거 하나 <script> 이게 태그다 

 

 

 

2. array 사용해보기

입력한 내용을 array 안에 오브젝트로 해서 넣어보자. 내가 작성한 내용은 갖고있긴 해야하니까..

const toDos = [];

function paintToDo(text) {
    
    .... // 위에 내용 그대로 아래 부분만 추가

    const toDoObj = {
        text : text,
        id : toDos.length + 1
    };
    
    toDos.push(toDoObj);
}

toDos 라는 array 를 선언 해줬고. 엔터를 치면 toDoObj 라는 오브젝트를 만들어서 그 안에

text 는 텍스트내용, id 는 array 의 length + 1 으로 선언한다음에 array 에 push 로 오브젝트를 밀어넣었다

고유 ID 를 좀 갖고싶어서 id 를 선언했는데 빈 array의 length 는 0이라 + 1 을 해준 것

 

또, 여기서 나온 고유한 번호로 지정할 id 가지고 아까 위에서 만든 <li> 에도 id를 달아줘보자. 

function paintToDo(text) {

	...
    
        const newId = toDos.length + 1;
        
	...
    
    	li.id = newId;			// 요기
}

 

 

 

3. local storage 에 object 형식으로 저장하기

1편에서 했던 것 생각하면서 localStorage.setItem

const toDos = [];

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

function paintToDo(text) {

	...

    const toDoObj = {
        text : text,
        id : newId
    };
    toDos.push(toDoObj);
    saveToDos();
}

이게뭐지??

난 bool true 를 저장했는데 왜 string true 를 가져와?

자바스크립트는 local storage 에 있는 모든 데이터들을 string 으로 저장하려고 한다. 그럼 어떡하지...

그래서 JSON.stringify 을 사용한다. 자바스크립트 object 를 string 으로 바꿔준다.

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

오오 ㅋ

 

 

 

4. local storage 에서 object 형식으로 가져오기

function loadToDos(){
    const loadedToDos = localStorage.getItem(TODOS_LS);
    if(loadedToDos !== null){
        console.log(loadedToDos);   // 로컬스토리지에 있는거 뭐라고 나올까?
    }
}

저장되어있는거 뭐라고 나올까?

다 string 이라... 내 object 어디갔어...

 

JSON.parse 을 사용한다. 반대로 string 을 object 로 바꿔준다.

function loadToDos(){
    const loadedToDos = localStorage.getItem(TODOS_LS);
    if(loadedToDos !== null){
        const parsedToDos = JSON.parse(loadedToDos);      // 이렇게 사용
        console.log(parsedToDos);
    }
}

JSON 은 JavaScript Object Notaion 의 줄임말이고

데이터를 전달할 때 자바스크립트가 그걸 다룰 수 있도록 object 로 바꿔주는 기능이다

 

가져 왔긴 왔는데 저 parsedToDos 를 어떻게 컨트롤할까?

forEach 는 array 를 위한 function 이고  parsedToDos 안에 있는 만큼 반복을 돌린다.  

한 덩어리? 가 나올 때마다 function 을 그 자리에서 바로 선언해서 console.log 을 찍어봤다

function(toDo) 에서 toDo 는 어디에 선언되어 가져온 특정 변수 명은 아니고. 그냥 ? 반복 돌릴 때 마다

parsedToDos 에서 나오는 한 덩어리? 의 가상 변수명? 이라고 생각하면 된다 

 

console 에 text (key) 를 가져왔다

 

paintToDo 메소드 호출

새로 고침 해도 내가 localstorage 에 넣었던 것들이 나오게 된다

 

 

 

5. 저장했던 리스트 삭제

음.. 이제 X 버튼을 누르면 저장되어 있던 리스트들을 삭제해보자

function paintToDo(text) {

...

    // 함수랑 이벤트 연결
    delBtn.addEventListener("click", deleteToDo); 

...

}

우리가 할일 치고 엔터 누르면 paint 하는 내용 보면 버튼 만드는 부분에 특정 이벤트랑 연결시켜놓자.

그래야 그 만들었던 버튼을 클릭하면 삭제 함수를 태우니까.

삭제 함수를 만든다 deleteToDo

 

function deleteToDo(event){
    const btn = event.target;
    const li = btn.parentNode;

    console.log(btn);
    console.log(li);
}

버튼의 event 는 뭐가 있을까? 

event.target 으로 우리가 눌렀던 버튼을 알게하자.

event.target

 

맞아.. target 해보니까 내가 눌렀던 버튼 맞긴 한데.. 부모가 누군지좀 볼까?

event.target.parentNode

버튼의 부모는 li 엘리멘트 너였구나

 

알았으니 저 li 부분 삭제해보자

 

function deleteToDo(event){
    const btn = event.target;
    const li = btn.parentNode;

    toDoList.removeChild(li);
    // toDoList 는 document.querySelector(".js-toDoList");
}

 

사라졌다

 

하지만 새로고침 하면 다시 나오게 된다. 방금 한건 클릭했을 때 html li 껍데기만 없앴으니까

껍데기 말고.. 실질적인 저장소 toDos [] 배열에 담겨져 있는 오브젝트들을 제거 해볼껀데

바꿔치기? 를 할 것이다. 다이렉트로 remove 하는게 아니라 원래배열 = 정리된배열 이렇게

그다음에 다시 정리된배열을 localstorage 에 저장

 

array.filter() 를 사용할 것이다. 말 그대로 배열에서 요소들을 필터링을 시켜서 새로운 배열을 만든다. 

리턴이 true 인 것 들만 모아서 새로운 배열을 만드는데 한번 보자

function deleteToDo(event){
    const btn = event.target;
    const li = btn.parentNode;

    toDoList.removeChild(li);
   
   
    const cleanToDos = toDos.filter(function(toDo){
        return toDo.id !== parseInt(li.id);
    });
    
    console.log(cleanToDos);
}

toDos 배열에서 filter 를 했다. 배열 안에 요소가 5개면 5번 반복 돈다.

어떻게 걸러낼껀데? 내용은 function 에 적어놨다. 

첫 바퀴 검사  function(toDo) 에서 toDo는 toDos ( 배열 ) 의 첫 번째 오브젝트겠지?

이거랑 li.id 는 지금 내가 클릭한 html 의 id 갖고와서 틀린지 비교한다.

 

당연히 틀려야하는게 (!==),  true 결과만 가지고 나가서 소수정예다 하고 새로운 배열을 만드니까.

그리고 parseInt(li.id) 를 한 이유는 html 에서 <li id> 보면 1이 string 이다. 비교가 안됨. 

 

function deleteToDo(event){
    const btn = event.target;
    const li = btn.parentNode;

    toDoList.removeChild(li);
   
    const cleanToDos = toDos.filter(function(toDo){
        return toDo.id !== parseInt(li.id);
    });

    toDos = cleanToDos;
    saveToDos();
}

 그다음에 소수정예로 true 나온 cleanToDos 배열을 원래 toDos 배열에다 엎어치기하고

saveToDos() 함수를 호출한다. (여기엔 toDos를 localstorage 에 저장하는 내용이 있음)

결국 필터링 한 거를 localstorage 에 저장하는 셈

 

 

삭제도 되고 로컬스토리지에도 안남아서 리프레쉬 해도 영영 돌아오지 않는다 

반응형
도움이 되셨다면 공감 클릭 부탁드리며
출처만 남겨주시면 글 내용은 마음껏 퍼가셔도 좋습니다 :)