티스토리 뷰
노마드코더 바닐라 JS로 크롬 앱 만들기 #3.4 ~ #3.6 강의 들으며 정리.
html
<form class="js-toDoForm">
<input type="text" placeholder="Write a to do">
</form>
<ul class="js-toDoList">
</ul>
to do list에 입력할 폼을 만들어주고 리스트를 표시할 ul 태그 작성
javascript
const toDoForm = document.querySelector('.js-toDoForm'),
toDoInput = toDoForm.querySelector('input'),
toDoList = document.querySelector('.js-toDoList');
function init(){
loadToDos();
}
init();
변수를 선언하고 loadToDos라는 함수를 실행할 init 함수 작성
const TODOS_LS = 'toDos';
function loadToDos(){
const loadedToDos = localStorage.getItem(TODOS_LS);
if(loadedToDos !== null){
// loadedToDos
});
}
else {
}
}
로컬스토리지에 저장된 정보가 있다면 투두리스트에 불러오고, 정보가 없다면 아무것도 실행하지 않도록 한다
function handleSubmit(event){
event.preventDefault();
const currentValue = toDoInput.value;
paintToDo(currentValue);
//입력하고 나면 아무것도 안남도록
toDoInput.value = '';
}
function init(){
loadToDos();
toDoForm.addEventListener('submit', handleSubmit);
}
init();
submit에 기본적으로 저장된 동작을 없애기 위해 preventDefault를 작성해주고, 투두리스트를 입력하는 input의 값을 변수로 저장해준다.
그리고 투두리스트에 입력할 값을 제출하고 나면 그 값이 보이도록 paintToDo라는 함수를 만들고, 입력하고 나면 input 안에 아무것도 남지 않도록 해준다.
let toDos = [];
function paintToDo(text){
//createElement - html에 있는 요소를 가져오지 않고, 새로운 요소를 생성
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;
// li들에게 아이디를 부여하기 위해. array의 첫번째는 0이므로 1을 더해준다
span.innerText = text;
//appendClild - 생성하는 요소를 그의 부모 요소에 넣음
li.appendChild(span);
li.appendChild(delBtn);
li.id = newId;
toDoList.appendChild(li);
const toDoObj = {
text: text,
id: newId
};
toDos.push(toDoObj);
//array toDos 안에 toDoObj를 넣어준다
saveToDos();
// push하고 난 다음에 saveToDos를 실행해야함. push 앞에 넣으면 아무것도 가져올 게 없으므로
}
각각 표시될 투두리스트 항목들을 array로 만들기 위해 toDos라는 변수를 작성한다.
그리고 이 array는 계속 변화해야 하므로 const가 아닌 let을 사용한다.
입력된 값을 투두리스트에 표시해 줄 paintToDo 함수 작성.
createElement를 이용해서 .js-toDoList라고 클래스를 붙여준 ul 태그 안에
li, button, span 태그를 만들어준다.
button 태그 안에는 innerText로 ❌표시를 넣어주고, 버튼을 누르면 투두리스트 항목을 삭제할 deleteToDo라는 함수를 실행하도록 addEventListner를 작성한다.
그리고 생성되는 투두리스트 항목에 아이디를 부여하기 위해 newId라는 변수를 작성.
span 태그 안에 입력하는 텍스트가 표시되도록 한다.
appendChild를 사용해서 li이 button과 span을 자식요소로 가질 수 있도록 하고, toDoList가 li를 자식요소로 가지도록 한다. 그리고 toDoObj라는 object를 작성해서 투두리스트 항목마다 부여된 아이디와 내용을 로컬스토리지에 저장할 수 있도록 값을 만들고 이 object를 push를 이용해서 toDos array 안에 넣어준다.
마지막으로 toDos를 가져와서 로컬스토리지에 저장할 saveToDos라는 함수를 실행한다.
// x표시 누르면 리스트에서 지워주는 함수
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);
//parseInt를 쓴 이유-> toDo.id는 숫자고 li.id는 string임. 그래서 li.id를 숫자로 만들어주기 위해
});
toDos = cleanToDos;
saveToDos();
}
//toDos를 가져와서 로컬스토리지에 저장하는 함수
function saveToDos(){
localStorage.setItem(TODOS_LS, JSON.stringify(toDos));
// 근데 원하는 결과가 안나옴.. object object로 나옴
// 로컬스토리지에는 자바스크립트의 데이터를 저장할 수 없기 때문.
// 로컬스토리지에 hello, true라고 저장해도 true라는 값은 도출되지만 boolean이 아니라 string타입임.
// 그래서 JSON.stringify라는 것을 사용해준다. 자바스크립트 오브젝트를 string으로 바꿔준다
}
❌표시가 있는 button을 클릭했을 때 항목을 삭제할 deleteToDo라는 함수를 작성한다.
event가 일어날 target을 btn이라는 변수로 저장하고, parentNode를 사용해서 btn의 부모노드를 찾아 변수 li로 저장.
그리고 toDoList의 자식 li가 삭제되도록 한다.
여기까지만 작성하면 투두리스트에서 항목이 삭제되기는 하지만, 새로고침 해보면 사라지지 않고 다시 나타난다.
그래서 완전히 사라지게 하기 위해 cleanToDos라는 변수를 만든다.
filter는 function의 조건에 맞는 요소를 새로운 배열로 생성하는 함수이다.
arr.filter(callback(element[, index[, array]])[, thisArg])
여기서는
toDos.filter(function(todo){
return toDo.id !== parseInt(li.id);
})
라고 작성했는데 toDos라는 array에 filter 함수를 사용하고, filter는 toDo의 아이디와 li의 아이디가 일치하지 않는 것만 반환하도록 한다.
그리고 toDo.id는 숫자이지만, li.id는 string타입이기 때문에 li.id도 숫자로 만들어주어야 조건을 정확히 시험할 수 있으므로 li.id를 숫자 타입으로 만들어주기 위해 parseInt를 사용한다.
parseInt() - 문자열 인자를 구문분석하여 특정 진수(수의 진법 체계에 기준이 되는 값)의 정수를 반환
그리고 toDos는 cleanToDos라는 값을 작성하고 saveToDos라는 함수를 실행한다.
saveToDos는 toDos를 가져와서 로컬스토리지에 저장하는 함수이다.
그냥 localStorage.setItem(TODOS_LS, toDos)이라고 작성하면, 로컬스토리지에서 확인해봤을 때 다음과 같은 결과가 나온다.
투두리스트 input에 무언가를 입력해도 이런 식으로 나오는데, 왜냐하면 로컬스토리지에는 자바스크립트의 데이터를 저장할 수 없기 때문이다. 만약 로컬스토리지에 hello라는 객체에 true라는 값을 저장해줘도, true라는 값은 도출되지만 이 true는 boolean이 아닌 string타입이다.
그래서 자바스크립트 오브젝트를 string으로 바꿔주는 JSON.stringify를 사용한다.
JSON.stringify() - JavaScript 값이나 객체를 JSON 문자열로 변환
json.stringify를 써주면 문자열로 데이터를 잘 받아온다.
function loadToDos(){
const loadedToDos = localStorage.getItem(TODOS_LS);
if(loadedToDos !== null){
//console.log(loadedToDos) -> 로컬스토리지에 있는 데이터를 string으로 불러옴
const parsedToDos = JSON.parse(loadedToDos);
//console.log(parsedToDos) -> parse해주면 object로 변환됨
parsedToDos.forEach(function(toDo){
paintToDo(toDo.text);
});
}
else {
}
}
그리고 마지막으로 loadToDos를 마저 만들어준다.
로컬스토리지에서 가져온 데이터 loadedToDos가 무언가 저장되어 있으면 paintToDo를 실행하여 투두리스트에 보여지도록 해주는데, 그냥 불러오면 이 데이터를 string으로 불러온다.
그래서 문자열을 자바스크립트의 값이나 객체로 반환하는 json.parse를 사용해주고, 그 값을 parsedToDos라는 변수로 저장해준다.
JSON.parse() - JSON 문자열의 구문을 분석하고, 그 결과에서 JavaScript 값이나 객체를 생성합니다.
그리고 parsedToDos를 투두리스트에 각각 보여지도록 해야하므로, paintToDo를 forEach를 사용해서 각각 실행되도록 해준다.
forEach() - 주어진 함수를 배열 요소 각각에 대해 실행
최종완성본
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');
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);
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);
});
}
else {
}
}
function init(){
loadToDos();
toDoForm.addEventListener('submit', handleSubmit);
}
init();
'개발 > javascript' 카테고리의 다른 글
[JS 스터디] 랜덤 숫자 생성 - Math.random(); (0) | 2022.11.16 |
---|---|
[JavaScript] 무한 롤링 배너 (0) | 2022.02.22 |
자바스크립트 실습 - Saving the User Name (0) | 2021.04.19 |
자바스크립트 실습 - Making a JS Clock (0) | 2021.04.19 |
event / if, else (0) | 2021.04.13 |
- Total
- Today
- Yesterday