> For the complete documentation index, see [llms.txt](https://westsilver.gitbook.io/study-script/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://westsilver.gitbook.io/study-script/nomad-script/vanillajs/momentum/to-do-list.md).

# To-Do List

3\. 할일 목록 저장하기 : 크롬 탭을 껐다 켜도 To-Do List을 항상 기록하여 보여줌 (오프라인 기능)

{% tabs %}
{% tab title="index.html" %}

```markup
<!DOCTYPE html>
<html>
<head>
    <title>Something</title>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="index.css">
</head>
<body>
    <div class="js-clock">
        <div class="js-title">
            <h1>00:00</h1>
        </div>
    </div>
    <form class="js-form form">
        <input type="text" placeholder="What is your name?" />
    </form>
    <h4 class="js-greetings greetings"></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="greeting.js"></script>
    <script src="todo.js"></script>
</body>
</html>
```

{% endtab %}

{% tab title="todo.js" %}

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

const TODOS_LS = 'toDos';

let toDos = [];

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();
}

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

function paintToDo(text){
    const li = document.createElement("li");
    const delBtn = document.createElement("button");
    const span = document.createElement("span");
    const newId = toDos.length + 1;
    delBtn.innerHTML = "❌";
    delBtn.addEventListener("click", deleteToDo);
    span.innerText = text;
    li.appendChild(delBtn);
    li.appendChild(span);
    li.id = newId;
    toDoList.appendChild(li);
    const toDoObj = {
        text: text,
        id: newId
    };
    toDos.push(toDoObj);
    saveToDos();
}

function handleSubmit(event){
    event.preventDefault();
    const currentValue = toDoInput.value;
    paintToDo(currentValue);
    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();
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**JSON**(Javascript Object Notation) : **데이터**를 전달할 때, 자바스크립트가 그것을 다룰 수 있도록 **Object로** 바꿔주는 기능이며 String을 Object로 변환해줄 수도 있음&#x20;

> ex) emoji(이모티콘)
>
> VSC - Extensions - emojisense 설치 - Extensions Settings - Edit in settings.json
> {% endhint %}

{% hint style="info" %}

### **For Each** : **배열(array)**&#xC5D0; 담겨있는 것들을 **각각 한 번씩** 함수를 **실행**시켜 줌

> 기본적으로 함수를 실행
> {% endhint %}

{% hint style="info" %}
search : delete child element mdn
{% endhint %}

{% hint style="info" %}

### **filter 메소드**

array의 모든 아이템을 통해 함수를 실&#xD589;**,** true인 아이템들만 가지고 새로운 array를 만들어 줌
{% endhint %}

{% hint style="info" %}
**parseInt 함수** : 문자열을 숫자로 변환시키는 방법
{% endhint %}
