자바스크립트로 크롬 시계 앱 만들기 [2]
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); // 로컬스토리지에 있는거 뭐라고 나올까?
}
}
저장되어있는거 뭐라고 나올까?
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 에서 나오는 한 덩어리? 의 가상 변수명? 이라고 생각하면 된다
새로 고침 해도 내가 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 으로 우리가 눌렀던 버튼을 알게하자.
맞아.. target 해보니까 내가 눌렀던 버튼 맞긴 한데.. 부모가 누군지좀 볼까?
event.target.parentNode
알았으니 저 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 에 저장하는 셈
삭제도 되고 로컬스토리지에도 안남아서 리프레쉬 해도 영영 돌아오지 않는다
댓글
이 글 공유하기
다른 글
-
논리연산자, null 병합 연산자 ??
논리연산자, null 병합 연산자 ??
2020.11.29 -
자바스크립트로 크롬 시계 앱 만들기 [3]
자바스크립트로 크롬 시계 앱 만들기 [3]
2020.10.15 -
자바스크립트로 크롬 시계 앱 만들기 [1]
자바스크립트로 크롬 시계 앱 만들기 [1]
2020.10.13 -
DOM / DOM Functions / Events handlers / if-else, and, or, === / 분리
DOM / DOM Functions / Events handlers / if-else, and, or, === / 분리
2020.10.12