최근 자바스크립트를 공부할 겸 간단한 TODO 프로그램을 만들어보았습니다. 부족한 점이 많지만 간단한 앱으로 배운 점을 바로 사용해볼 수 있고, 앞으로 부족한 점은 조금씩 개선해보려고 합니다. 코드는 몇 줄 안 되지만 코드를 작성하며 배운 점들을 기록해두고자 합니다.
1. 요구사항
2. 구현
3. 더 나아가
_____
요구사항
가장 필수적인(간단한) 기능만 담은 기능을 먼저 구현하고자 했다(UI를 그림판으로 한 게 좀 문제가 있어 보인다...).
개략적으로 위와 같은 기능을 먼저 구현하고자 하였고, 요구사항을 정리하면 아래와 같다.
1. 할 일을 입력 후 엔터 혹은 ➕를 클릭하면 할 일이 등록된다.
2. 완료한 일에 대해 ❌를 클릭하면 해당 작업이 삭제된다.
3. 위 사항은 브라우저를 새로고침해도 유지되어야 한다.
구현
구현 시 고려한 점은 다음과 같다(코드).
1. 배열[1]을 이용해 할 일을 관리한다.
2. 새로고침 시에도 유지되어야 하기에 localStorage[2][3]를 사용한다(배열과 동기화).
3. 추가, 삭제 메서드가 대칭적 구조를 가지도록 노력했다(둘 다 배열의 요소를 인자로 받도록 통일).
4. 각 버튼 클릭 시, 즉 이벤트 리스너에 등록되는 콜백 함수에서 작은 함수들을 호출하는 구조를 취한다.
5. 배열을 사용하기에 반복문 대신 배열 API를 사용[5]한다.
이 외 내용은 하단을 참고[6]한다.
더 나아가
자바스크립트 연습을 위해 간단한 기능만을 구현했지만 추가할만한 사항을 남겨둔다(시간이 나면 고민해보기로).
- 완료된 작업의 경우 삭제 외에 취소선을 표시한 후, 가장 하단으로 이동시킨다.
- 사용자의 실수를 예방하고자 ✅, ❎를 클릭 시 모달 창으로 한 번 더 확인한다.
- 작업이 많아질 경우를 고려해 스크롤 혹은 페이지당 갯수 제한을 둔다.
외에도 현재 ✅, ❎를 클릭할 때마다 배열 변경 후 웹 저장소(localStorage)에 동기화되는데 클릭 시엔 배열에만 반영하고, 브라우저 종료 혹은 새로고침 시에만 저장소에 반영해도 되지 않을까 하는 생각을 했다. 더 나아가 최종적으로는 달력을 추가해 요일별 할 일로 확장할 수 있을 것 같다.
_____
1. 자바스크립트의 배열은 자바 등의 그것과 다르게 연결 리스트의 개념으로 추가, 삭제에 유연하기 때문이다.
2. localStorage는 key, value 형식의 저장소인데 string 타입만을 지원하며 5MB 정도의 용량 제한이 있다. 따라서 localStorage만을 이용해 데이터를 관리하지 않고 기본적으로 배열을 이용하되 추가, 삭제 시 배열의 데이터를 저장소와 동기화하였다.
3. 이 외에도 여러 저장소, Cookie 등이 있고 각각의 쓰임을 비교하여 알아둘 필요가 있다. 이를테면 sessionStorage는 localStorage와 다르게 만료 기간이 존재한다. 개략적으로 정리하면 아래와 같다.
- sessionStorage
- localStorage와 마찬가지로 새로고침 시 유지된다.
- 반면 새 탭을 열거나 브라우저를 닫을 때 유지되지 않는다.
- 게시글 임시 저장 등의 용도로 사용된다.
- IndexedDB
- localStorage와 다르게 대용량 데이터를 저장할 수 있고, 기능도 많다.
- 다만 저수준 API를 제공한다는 점에서 부담이 있다.
- Cookie
- 서버 요청 시 같이 담겨 간다.
- localStorage보다도 훨씬 작은 4KB 정도의 용량 제한을 가진다.
- sessionStorage와 마찬가지로 만료 기간이 존재한다.
- 서버 사이드 렌더링[4] 시점에 Cookie 데이터를 알 수 있기에 로딩 시간 단축에 이용할 수 있다.
- 서버 요청 시 같이 담겨 간다.
5. 여기에선 배열에 직접 사용하여 상관 없지만 부연하자면 목록(li tag)에 이벤트 리스너를 바인딩해주는 부분에 있어서도 getElementsByTagName() 등을 사용하면 유사배열인 HTMLCollection[7]을 반환하므로 forEach를 사용할 수 없다. 따라서 NodeList를 반환하는 querySelectorAll()을 사용하는 것도 하나의 방법이다.
6. 외에 구현 시 고려한 디테일한 부분은 아래와 같다.
- JS, CSS의 역할을 구분
- CSS 선택자를 사용할 수 있는 querySelector() 사용
- DOM[8] 생성 및 삭제[9]에 대해 익숙치 않아서 공부 필요
- DOM 생성 시 createElement()로 노드 객체 생성 후, appendChild()를 통해 DOM 트리에 연결 필요
- DOM 삭제 시 removeChild() 이용
- 개념이 없어서 연결 시 appendChild()를 삭제 시 remove()를 사용했는데 대칭적이지 않다는 생각이..
- <input type="submit"> vs <button>
7. HTMLCollection vs. NodeList
- Hyungsang Han] HTMLCollection vs. NodeList
- Celeste Layne] HTMLCollection vs. NodeList
8. DOM
- PoiemaWeb] DOM(Document Object Model)
- JAVASCRIPT.INFO] DOM 트리
9. removeChild()를 이용한 삭제는 엘리먼트 삭제가 아닌, 부모와 자식간의 관계를 끊는 것이라고 한다(참고). 다만 새로 추가된 remove()는 노드를 메모리에서 삭제한다. 한편 appendChild() 외에 append()도 추가되었다.
_____
참고
댓글