JavaScript

[JavaScript] 페이지개발 : localstorage 변경

vhxpffltm 2019. 12. 6. 23:53

이전시간에 localstorage가 무엇인지 어떻게 만들고 작용하는지 알아보았다.

 

이번에는 새 localstorage안에 여러 값을 넣고 삭제해보는 작업을 해보자.

 

우선 코드는 아래와 같다.

 

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
<title>123</title>
    <link rel = "stylesheet" href="index.css" >
</head>
<body>
    <div class="js-clock">
    <h1 class = "js-title">00:00</h1>
 
    </div>
    <form class="js-form form">
        <input type = 'text' placeholder="what is your name??"/>
    </form>
    <h4 class="js-greet greet"></h4>
 
    <form class="js-todoform">
        <input type="text" placeholder="Write a to do"/>
    </form>
    <ul class="js-todolist"> </ul> 
 
    <script src="clock.js"></script>
    <script src="hi.js"></script>
    <script src="todo.js"></script>
</body>
</html>
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

추가된 코드를 보면 우리는 form태그를 바탕으로 text를 넣는 페이지를 구성한다.

클래스 이름이 todoform과 todolist라는 태그들이 오늘 만들 내용이다.

 

todo.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
const todoform = document.querySelector(".js-todoform");
const todoinput = todoform.querySelector("input"); //input 태그이름을 가지는 todoform에서
const todolist = document.querySelector(".js-todolist");
 
const TODO_LS = "todo";
 
let todos = []; // 할일을 저장할 배열
 
function deletetodo(event){
    //.target : 타겟의 부모, 여기서는 id를 기준으로 지울거다.
    const btn = event.target;
    const li = btn.parentNode;
    todolist.removeChild(li); //HTML에서만 삭제된다.
    const cleantodos = todos.filter(function(arr){
        return arr.id !== parseInt(li.id);
    }); //cleantodos 는 줄어들지만 todos 는 그대로다.
    //filter는 array의 모든 아이템을 통해 함수를 실행하고\
    //true인 아이템들만 가지고 새로운 array를 만듬
    todos = cleantodos;
    savetodo();
}
 
function savetodo(){
    localStorage.setItem(TODO_LS,JSON.stringify(todos)); 
    //local 스토리지에 저장하기위함, 근데 JS는 string만 저장할 수 있다.
    //그게 JSON stringfy
}
 
function painttodo(text){
    const li = document.createElement("li"); //HTML을 우리가 원하는걸 만든다.
    const deletebtn = document.createElement("button");
    deletebtn.innerText = "O_O";
    const span = document.createElement("span");
    const newID = todos.length+1// li에 아이디를 주기위함
    deletebtn.addEventListener('click',deletetodo);//클릭했을때 지움
    span.innerText = text;
    li.appendChild(span);
    li.appendChild(deletebtn);
    //비어있는 li에 버튼만들고 sapn도 만들고 li안에 span도 넣고
    //span을 li안에 넣고 버튼을 li안에 넣음
    todolist.appendChild(li);//그리고 이 li를 ul에 넣음
 
    //웹 창에서 엔터를 눌렀을때, 엘리먼트가 만들어짐
    //js로 원하는 태그에 무언가를 만들고 이벤트로서 만듬
    li.id = newID;
    const todoobj = {
        text: text,
        id: newID
    };
    todos.push(todoobj); // 이 객체를 배열에 저장했다.
    savetodo();
}
 
function handle(event){
    event.preventDefault();
    const currentval = todoinput.value;
    painttodo(currentval);
    todoinput.value = "";
}
 
function loadtodo(){
    const loadtodos = localStorage.getItem(TODO_LS);
    if(loadtodos !== null){
        const parsetodo = JSON.parse(loadtodos); // 오브젝트로 변환
        parsetodo.forEach(function(a) {
            painttodo(a.text); // 새로고침을 해도 로컬 데이터에 있기때문에 입력값이 계속 뜬다.
        });
    }
}
 
function init(){
    loadtodo();
    todoform.addEventListener("submit",handle);
}
 
init();
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

코드가 길다. 하나씩 살펴보자. 먼저 가장 아래에 init() 함수부터 시작한다.

 

그리고 가장 위애 우리가 사용할 변수들이 있다. 각 클래스 이름과 태그이름을 갖는 문서요소를 뜻하게 될 것이다.

 

loadtodo(), todoform.addEventListner()

 

loadtodo()함수는 localsotrage에 아무것도 없다면 작동하지 않는다. 하지만 우리는 리스트들을 계속 보여주기위해 바로 아래에 todoform의 이벤트 리스너를 제출하도록 호출한다.

 

항상 handle() 함수를 'submit' 하도록 실행된다. handle 함수는 이전에 했던 'handlesub' 함수와 비슷하다. 

preventDefault() 로 엔터의 이벤트를 무시하도록 하고 현재 값을'input'태그의 값으로 가져온다음 painttodo()함수에 넘겨주고 'input'태그의 값을 빈 문자열로 만들어준다.    

 

painttodo()

 

우리는 입력한 텍스트를 엔터로 치면 그것을 화면에 여러줄에 걸쳐 나타내야한다. 즉, 새로운 HTML 문서요소가 필요하다. painttodo() 함수는 처음에 'li' 태그와 버튼, 그리고 sapn태그를 생성한다.

 

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

    const deletebtn = document.createElement("button");

    deletebtn.innerText = "O_O";

    const span = document.createElement("span");

 

 

 

 li태그에 'id'를 주기위해 todolist의 길이에 +1을 해준다. 나중에 li 태그에 접근하기 위해 만들어 둔다. 다음에 버튼을 클릭했을 때, 지우는 이벤트인데 좀있다 살펴보고 이후에 <li>태그안에 span과 button 태그를 넣어야 한다. 그것이 appendChild() 함수를 통해 합칠 수 있다. 그리고 이 <li> 태그를 todolist 태그에 넣어준다.

 

이제 필요한 태그를 생성해서 만들었고 localstorage에 들어가야 할 객체를 정의하고 이것을 todos 배열에 하나씩 넣어준다. 그리고 이 객체를 담은 배열을 localstorage에 저장하도록 savetodo()함수를 호출한다.

 

 

 

 

savetodo()

그래서 이 함수는 쉽다. 위 코드처럼 localstorage에 저장을 하는데 JS는 string만 저장할 수 있기 때문에 string으로 변환하여 저장한다. 변환하는 코드는 JSON.strigfy()이다. 앞의 TODO_LS는 localstorage에서 사용할 key값이다.

 

deletetodo()

 

지우는것은 좀 복잡하다. 지울때에는 2가지를 해야한다. 하나는 localstorage에서 지운뒤 저장해야하고, 다음은 HTML에서 지워야 한다.

먼저 HTML을 지우는데 각 버튼마다 그 버튼의 부모, 즉 li를 지워야 한다. 그 코드는 아래와 같다. 

//.target : 타겟의 부모, 여기서는 id를 기준으로 지울거다.

    const btn = event.target;

    const li = btn.parentNode;

 

버튼을 보면 우리는 그 버튼의 부모의 id값을 확인할 수 있다.

 

 

위의 그림과 같이 생성된 태그와 내용을 볼 수 있다. button의 부모는 console.dir() 을 통해 확인할 수 있는데 내용이 너무 많아 생략한다.

그 버튼의 부모노드를 찾아서 그것을 todolist에서 제거하면 HTML에서의 제거는 끝이난다.

 

하지만, localstorage에서는 계속 남아있기 때문에 이제 localstorage에서 제거하는 작업이 필요하다.

 

 

버튼을 눌러 HTML에서 제거했지만 오른쪽과 같이 localstorage에는 남아있다. 이제 수정해보자.

먼저 filter()라는 메서드가 있는데 이것은 filter는 foreach에서 함수를 실행하는 것과 같이 각각의 item이 함께 실행된다. 

이걸로 어떤 배열을 만들어내고 모든 todos의 id가 <li> 태그의 id가 같지 않을때 값을 리턴하는데 결국 true인값만을 취한것이다. 아래의 예시를 보자

 

 

위의 출력은 삭제를 누르고 나서의 cleantodos 변수의 값과 todos의 값이다.

위의 출력을 보고 filter(function(arr)) 함수를 이해하기 바란다.

이제 todos를 변경된 cleantodos로 바꿔주면 localstorage를 변경할 수 있다.