자바스크립트 to-do 마지막 과정 #3를 이어서 진행한 내용을 풀어내려고 한다.
리스트 객체를 배열에 저장하고, 화면에 출력 후 삭제까지 할 수 있도록 하였다. 이번 게시물에 정리할 내용은 할 일 완료 체크를 해주고 로컬스토리지에 저장해서 새로고침시에도 데이터가 남아있도록 해줄것이다!
4단계 : 상태 토글 만들기
체크박스 추가
클릭시 done:true 로 변경
새로고침 클릭시 done:false로
완료했다는 체크 표시를 하기 위해서 할 일 옆에 체크 박스를 만들어준다.
<input type="checkbox"> 를 js에서 만들어준다.
const checkbox = document.createElement('input')
checkbox.type = 'checkbox'
checkbox.checked = todo.done
document.createElement('input') input태그를 새로 만들고, 타입은 checkbox로 지정해주었다. 현재 완료된 상태인걸 구별하기 위해서는 done:true에 따라서 체크박스를 체크된 상태로 보여준다.
checkbox.addEventListener('change', () => {
todo.done = checkbox.checked;
renderTodos();
});
체크박스가 리스트 옆에 생성이 되고, 체크박스를 click하면 chage이벤트 발생한다.
renderTodos()로 배열의 변경 상태를 다시 화면에 반영해서 줄긋기 스타일로 바뀌게 함.
const span = document.createElement('span');
span.textContent = todo.text;
if (todo.done) {
span.style.textDecoration = 'line-through';
span.style.opacity = 0.6;
}
만약 todo.done이 true라면 textDecoration : 'line-through' 줄긋기와 동시에 opacity를 줘서 살짝 흐리게 효과를 주면서 완료된 표시상태를 확인할 수 있었다.
💭 막혔던 부분 체크박스를 html에 만들어야하는지 알고 어디에 구조를 짜야하는지 헷갈렸다.
createElement()의 쓰임새와 역할을 이제 정확히 알게되었는데, html이랑 약간의 충돌이 생겨났다. 화면에 보이는걸 html에 적는게 아닌가? 라는 단순한 궁금증이 생겨나서 추가적으로 어떤걸 만들어야할 때 왜 js에서 createElement()를 써야하는건지?
이유1. 예를들어, 입력한 할 일의 개수는 동적이기 때문이다.
할 일이 하나 있을 때는 html에 직접 입력하여 가능하지만, 사용자가 계속 입력해서 추가추가 될 경우엔 html에 미리 만들 수 없다.
즉, 입력될 때마다 새로운 요소를 만들어야하기때문에(동적으로 생성해야하기때문에) js에서 createElement()를 쓴다고 한다.
이유2. 배열의 데이터를 기반으로 화면을 구성해야하니까.
화면을 출력할 때 기준은 #2에서 만들었던 todos배열이다.
todos.forEach()를 순회하면서 배열의 항목 수만큼 li, checkbox, span을 만들어야한다. 그래서 js로 요소를 동적으로 만드는 게 필수적이다.
이유3. 자바스크립트가 DOM 조작하는 방식이기 때문에
js는 기존 html을 그대로 쓰기보다 필요한 양과 구조만큼 js로 만들어서 DOM에 붙이는게 효율적이기 때문이다. *심화느낌이넹
localStorage.setItem(key, value) 저장
localStorage.getItem(key) 꺼내오기
localStorage.removeItem(key) 삭제
*localStorage는 문자열만 저장 가능하므로 배열/객체를 저장하려면 아래내용 참고
Json.stringify() 객체 -> 문자열로 바꿈
Json.parse() 문자열 -> 다시 객체로 바꿈
현재는 새로고침하면 리스트가 사라졌다. 그래서 할 일을 브라우저에 저장해서 새로고침을 해도 유지되도록 만들것이다.
const saveTodos = () => {
localStorage.setItem('todos', JSON.stringify(todos));
};
현재 할일 목록 배열들을 JSON.stringify(todos)를 이용하여 배열을 문자열로 변환을 우선 해준다. localStorage.setItem() 문자열을 브라우저에 저장해주는데 todos라는 key 이름으로 저장해준다.
저장위치는 saveTodos()로 로컬에 저장
왜 객체는 저장이 안될까??? 다시 복습을 하니까 JSON.strigify()가 꼭 필요하다는 점 발견.
localStorage는 "텍스트 파일처럼 문자열만 저장" 가능하니까
JS 객체/배열을 넣으려면 "문자처럼 포장"해야 된다는 점 알 수 있었다. 다음엔 빼먹지 말고 같이 적용해줘야지,,
이제 불러오기를 하면 되는데
const saved = localStorage.getItem('todos');
if (saved) {
todos.push(...JSON.parse(saved));
renderTodos();
}
localStorage.getItem()저장된 문자열 데이터를 불러오고 JSON.parse()그 문자열을 다시 객체/배열로 바꿔준다. 불러온 배열을 todos배열에 스프레드 연산자 사용해서 넣어주고 화면에 다시 뿌련준다. todos.push(...Parse) --- renderTodos()
객체/배열을 저장하려면 문자열로 바꿔야하고, 불러올때는 다시 객체로 바꿔야한다는 구조가 코드도 치기 익숙하지 않은데 저런 생각은 당연히 못했으니 보고 이해하려고 해도 헷갈렸지만 꼭 이렇게 해야하는거니까 현재로써는 완벽한 이해를 바라기 보다 익숙해지도록 많이 사용해보고 흐름과 구조를 이해를 하는게 맞는거 같당..ㅎㅎ
학원에서 프로젝트 진행할 때 localStorage 영역은 어려운 느낌이라는 생각이 강해서 내가 사고를 생각하고 진행하기 보다 처리하기 바빴던 영역이였다.
근데 간단한거긴 해도 왜 필요한지, 어떻게 써야하는지, 언제 써야하는지 감이 조금 생겨서 자신감도 점차 오르려고 한다. 확실히 나는 계속 반복해서 하는 게 맞는거 같다..현재 속도에서 나중에 더 빠른 속도를 낼 수 있도록 공부도 꾸준히하고 프로젝트도 준비해서 취뽀해야지!><