멋사 세션에서 자바스크립트 사용법을 배운 지 2주째.
세션은 운영진님의 코드를 따라치는 식으로 진행되는데 하다 보니 뭔가 만들고 싶어 졌다.
그래서 만들어본 투두리스트
일요일에 시간 가는 줄 모르고 만들었다.
기획 및 디자인
디자인 작업 전 구현할 기능을 아래와 같이 정리했다.
1) 할 일을 입력하고 추가 버튼을 누르면 리스트에 추가
2) 리스트에서 삭제 버튼을 누르면 요소 삭제
3) 리스트에서 체크 박스를 누르면 완료 표시
4) 날씨 API 사용해서 지역 및 현재 날씨 표시
디자인은 Figma를 사용했다. 이제 PPT로 디자인은 그만😇
사용 폰트: Open Sans
사진 출처: @Seokiski_film
디자인 아이디어는 친구가 며칠 전 찍은 사진에서 얻었다. 김작가 넌 최고야 사진에 맞춰서 체크박스도 직접 만들기🙋♂️
JavaScript 주요 기능
1) 할 일을 입력하고 추가 버튼을 누르면 아래 리스트에 추가
<!-- index.html -->
<div class="title-container">
<div class="input-container">
<h1>what are you doing today?</h1>
<div class="input-item">
<input type="text" class="input-box">
<button type="button" class="add-button"><img src="images/add.svg"></button>
</div>
</div>
</div>
let addButton = document.querySelector(".add-button");
let itemList = []
addButton.addEventListener("click", addItem)
function addItem() {
let inputBox = document.querySelector(".input-box")
// 할 일을 입력했을 때 itemList로 push
if (inputBox.value != "") {
itemList.push(inputBox.value)
inputBox.value = ""; //입력값 초기화
}
// 입력하지 않았을 때 'placeholder'속성으로 메시지 표시
else {
inputBox.setAttribute('placeholder', 'please fill in this field!')
}
showList();
}
빈 리스트 itemList를 선언하고 할 일을 입력했을 때 리스트에 값이 쌓이도록 했다. 입력하지 않았을 때에는 placeholder를 사용해서 메시지를 띄웠다.
* 변수 선언에 let을 사용했다. let은 변수에 값을 재할당하는 것이 가능하지만 const는 불가능하다.
* document.querySelector(selectors)는 문서 내 selector와 일치하는 element를 반환한다.
* element.setAttribute(attributename, attributevalue)를 사용하면 선택한 element의 속성 값을 정할 수 있다.
2) 리스트에서 삭제 버튼을 누르면 요소 삭제
<!-- index.html -->
<div class="item-container">
<ul>
<li>
<input type="checkbox">
<label></label>
<p>할 일</p>
<button class="delete-button id="0"></button>
</li>
</ul>
</div>
function showList() {
let list = "<ul>"
for (let i = 0; i < itemList.length; i++) {
list += "<li><input type='checkbox'><label></label></input><p>" + itemList[i] + "</p><button class='delete-button' id=" + i + "></button>" + "</li>"
}
list += "</ul>";
document.querySelector(".item-container").innerHTML = list;
// 리스트 요소 삭제
let deleteButtons = document.querySelectorAll(".delete-button");
for (let i = 0; i < deleteButtons.length; i ++) {
deleteButtons[i].addEventListener("click", deleteItem);
}
}
addEventListener를 사용해 삭제 버튼 클릭 시 deleteItem 함수를 실행하도록 했다.
* element.innerHTML를 사용하면 html 코드를 element에 포함시킬 수 있다.
* document.querySelectorAll(selectors)은 문서 내 selector와 일치하는 element의 리스트(NodeList)를 반환한다.
function deleteItem() {
let id = this.getAttribute("id"); //선택한 요소의 특정 속성값을 가져옴
itemList.splice(id, 1); //itemList 배열 id인덱스에서 한 개 요소 제거
showList();
}
deleteItem 함수 실행 시 요소의 id값을 가져와서 itemList에서 제거했다.
* splice()를 사용하면 배열의 요소를 삭제, 교체, 추가할 수 있다.
3) 리스트에서 체크 박스를 누르면 완료 표시
/* index.css 체크박스 이미지 변경 */
/* 기존 체크 박스는 안 보이게 설정 */
input[type=checkbox] {
display:none;
}
/* label이 있는 경우(빈 박스) */
input[type=checkbox] + label {
width: 28px;
height: 28px;
margin-right: 13px;
margin-left: 3px;
background-image: url('images/empty-box.svg');
background-size: cover;
}
/* checked가 추가되고 label이 있는 경우(체크 박스) */
input[type=checkbox]:checked + label {
width: 30px;
height: 30px;
background-image: url('images/check-box.svg');
background-size: cover;
}
/* index.css 글자 스타일 변경 */
ul li {
height: 41px;
display: flex;
align-items: center;
border-bottom: 1px solid #828E93;
}
ul li.checked {
text-decoration: line-through;
font-family: Open Sans;
font-style: italic;
font-weight: 600;
}
let checkList = document.querySelector('.item-container');
checkList.addEventListener("click", event => {
// 클릭한 요소의 태그 명이 label인 경우(박스이미지)
if (event.target.tagName === 'LABEL') {
// parentNode(li)에 'checked'없으면 추가, 있으면 제거
event.target.parentNode.classList.toggle('checked');
let cbox = event.target.parentNode.firstChild;
// 체크박스가 체크 된 상태면 false로, 아니면 true로 변경
if (cbox.checked == true) {
cbox.checked = false;
}
else {
cbox.checked = true;
}
}
})
체크 박스 클릭 시 이미지와 글자 스타일 모두 바꾸고 싶었다.
🌊글자 스타일 변경
: 체크 박스 클릭 시 parentNode의 클래스 값 토글링
🌊이미지 변경
: 체크 박스 클릭 시 선택된 상태(checked == true)라면 false로, 아니라면 true로 변경
* console.log(event.target.parentNode.firstChild)을 하면 <input type="checkbox">가 나타난다.
* element.classList.togle()을 사용하면 클래스 값을 토글링(클래스가 존재한다면 제거, 존재하지 않으면 추가)할 수 있다.
* element.firstChild는 노드의 첫 번째 자식(없으면 null)을 반환한다.
4) 날씨 API 사용해서 지역 및 현재 날씨 표시
날씨 API는 openweathermap을 통해 사용했다.
분량 조절 실패로 API 관련 글은 다음번에🥺
프로젝트 결과
코드 하나하나 검색해보면서 자바스크립트랑 쪼금 더 친해진 느낌🙃
이론만 공부하다가 오랜만에 직접 이것저것 구현해보니까 기분 좋다.
전체 코드는 아래 깃허브에서 확인 가능 가능
참고 자료
자바스크립트로 투두 리스트 만들기
날씨 정보 보여주기
'LIKELION 9th' 카테고리의 다른 글
[멋쟁이 사자처럼] 토이프로젝트 TRIP-LOG 완성과 회고 (4) | 2021.06.30 |
---|---|
[Django] SECRET_KEY 분리하기(Django Secret Key exposed on GitHub 메일) (0) | 2021.06.05 |
[멋쟁이 사자처럼] 토이프로젝트 아이디어 발표🌊 (0) | 2021.06.03 |
[Django] 템플릿 상속 및 css 파일 적용하기(feat. 내비게이션 바) (0) | 2021.05.29 |
[멋쟁이 사자처럼] Django로 블로그 만들기3 (댓글 쓰기) (0) | 2021.05.25 |