| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
- reactnativecli
- 개발일기
- leetcode
- 프로그래머스
- [파이썬 실습] 심화 문제
- 개발공부
- 삼항연산자
- 엘리스 ai 트랙
- 프론트개발공부
- 자바스크립트 split()
- 프론트개발
- 엘리스
- 간단한 날씨 웹 만들기
- 코드스테이츠
- 자바스크립트 sort()
- RN 프로젝트
- 자바스크립트 날씨
- 리트코드
- 부트캠프
- JavaScript
- 자바스크립트 날씨 웹 만들기
- 엘리스 AI 트랙 5기
- HTML
- [AI 5기] 연습 문제집
- 코딩부트캠프
- [파이썬 실습] 중급 문제
- [파이썬 실습] 기초 문제
- 날씨 웹 만들기
- 자바스크립트 reduce()
- 자바스크립트
- Today
- Total
개발조각
[JavaScript] 투두리스트 만들기(추가, 완료여부, 삭제) 본문
최근 어느 한 회사에서 코딩테스트를 보러 갔는데
인터넷 연결을 끊은 상태에서 40분 동안 html, css, javascript으로 투두리스트를 만드는 테스트였습니다.
(코딩 테스트라 해서 알고리즘인 줄 알았더니 과제테스트라 당황했다...)
리액트, 자동완성, 구글검색, chatGPT에 익숙해져 있는 나에게 인터넷 끊긴 상태로 javascript로만 만들라 하다니...
머릿속에는 아무런 기억이 나지 않았고, 노드 추가하는 방법이 기억이 안 나서 테스트를 망쳤습니다...ㅎㅎ
또 이런 일이 일어날 수도 있고, 이번기회에 javascript로만 투두리스트를 만들어보면 좋을 것 같습니다!!
이번에 만들어본 투두리스트는 JavaScript로만 만들었으며
리스트 추가, 완료여부확인 및 체크, 리스트 삭제 기능을 넣어서 만들어보았습니다. (로컬스토리지에 데이터를 담지는 않았습니다.)
css는 간단 요소만 작업했습니다.
구현화면

HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>투두리스트 만들기</title>
<link rel="stylesheet" href="./index.css" />
<script src="./index.js" defer></script>
</head>
<body>
<div class="to_do_wrap">
<h1>오늘의 할 일은?</h1>
<form>
<input type="text" />
<button>+</button>
</form>
<ul class="list_wrap"></ul>
</div>
</body>
</html>- <script>태그의 defer속성은 페이지가 모두 로드된 후에 외부 스크립트가 실행됩니다.
- <form>태그로 리스트 추가 시 기능 구현 예정
JavaScript 전체 코드
const form = document.querySelector("form");
const input = document.querySelector('input[type="text"]');
const ul = document.querySelector("ul");
// 리스트 완료 여부
const completeItem = (e) => {
// console.log(e.target.nextSibling);
// 체크여부 확인
const { checked } = e.target;
// 체크버튼의 다음 형제요소 즉 span
const target = e.target.nextSibling;
// 체크여부 확인 후 true일 경우 span에 밑줄, false일 경우 span의 밑줄 없애기
if (checked) {
target.style.textDecoration = "line-through";
} else {
target.style.textDecoration = "";
}
};
// 리스트 삭제
const delItem = (e) => {
// 삭제버튼의 부모요소를 찾아오고 그 요소를 삭제해야 된다.
const target = e.target.parentElement; // 지워야하는 리스트 요소
target.remove();
};
// 리스트 추가
const addItem = (text) => {
if (text) {
const li = document.createElement("li");
const div = document.createElement("div");
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
const span = document.createElement("span");
const button = document.createElement("button");
span.innerText = text;
button.innerText = "삭제";
// 리스트에 추가 할 때마다 추가된 리스트에는 리스트 완료 여부, 리스트 삭제 기능이 작동되어야 되기 때문에 추가 부분에 이벤트 작성
// 체크버튼 클릭시 리스트 완료 여부 확인 및 표시
checkbox.addEventListener("change", completeItem);
// 삭제버튼 클릭시 해당 요소의 리스트 삭제
button.addEventListener("click", delItem);
// append():여러개 요소 추가, appendChile(): 한개 요소 추가
div.append(checkbox, span);
li.append(div, button);
ul.appendChild(li);
}
};
const handler = (e) => {
e.preventDefault(); // 새로고침 방지
// submit 할 때마다 리스트가 추가되기 때문에 submit부분에 이벤트 작성
addItem(input.value);
input.value = ""; // input 공백으로 초기화
};
form.addEventListener("submit", handler);
JavaScript 코드 분석
+버튼 클릭 시
const form = document.querySelector("form");
const input = document.querySelector('input[type="text"]');
const ul = document.querySelector("ul");
const handler = (e) => {
e.preventDefault(); // 새로고침 방지
// submit할 때마다 리스트가 추가되기 때문에 submit부분에 이벤트 작성
addItem(input.value);
input.value = ""; // input 공백으로 초기화
};
form.addEventListener("submit", handler);- 이벤트리스터를 등록할 때, 버튼의 클릭이 아닌 click이 아닌 form을 submit 할때 즉 제출될 때 지정
- submit할 때마다 리스트가 추가되기 때문에 submit부분에 이벤트를 작성해야 된다.
form에서 submit이벤트 발생
- form내부에 있는 input에서 엔터를 입력한 경우
- form 내부에 있는 submit 타입의 버튼을 클릭한 경우
리스트 추가 기능
// 리스트 추가
const addItem = (text) => {
if (text) {
const li = document.createElement("li");
const div = document.createElement("div");
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
const span = document.createElement("span");
const button = document.createElement("button");
span.innerText = text;
button.innerText = "삭제";
// append():여러개 요소 추가, appendChile(): 한개 요소 추가
div.append(checkbox, span);
li.append(div, button);
ul.appendChild(li);
}
};- ul안에 li를 추가하기 위해서는 createElement로 생성해 주고 appendChild, append로 원하는 위치에 태그를 추가해 주어야 된다.
- innerText로 태그 안의 내용을 넣어주었다.
코드가 복잡해 보이지만 이 리스트 ui를 만들기 위해 이와 같이 작성했다.

<li>
<div>
<input type="checkbox">
<span>잠자기</span>
</div>
<button>삭제</button>
</li>
완료여부 확인 및 체크하기
// 리스트 추가
const addItem = (text) => {
if (text) {
const li = document.createElement("li");
...
span.innerText = text;
button.innerText = "삭제";
// 체크버튼 클릭시 리스트 완료 여부 확인 및 표시
checkbox.addEventListener("change", completeItem);
// 요소추가
div.append(checkbox, span);
li.append(div, button);
ul.appendChild(li);
}
};- 리스트에 추가할 때마다 추가된 리스트에는 완료 여부 기능이 작동되어야 되기 때문에 추가 부분에 이벤트 작성
// 리스트 완료 여부
const completeItem = (e) => {
// 체크여부 확인
const { checked } = e.target;
// 체크버튼의 다음 형제요소 즉 span
const target = e.target.nextSibling;
// 체크여부 확인 후 true일 경우 span에 밑줄, false일 경우 span의 밑줄 없애기
if (checked) {
target.style.textDecoration = "line-through";
} else {
target.style.textDecoration = "";
}
};- 밑줄 그어지기 원하는 곳은 체크가 된 부분의 형제인 span태그이다.
- 그러므로 nextSibling을 사용해 주어야 된다.
- input태그의 checkbox임으로 e.target.checked를 하면 체크여부를 확인할 수 있다.
부모(parent) 노드 탐색
- parentNode : 부모 노드를 리턴합니다.
자식(child) 노드 탐색
- childNodes : 자식 노드 목록을 NodeList 형태로 리턴합니다.
- firstChild : 자식 노드 중, 첫번째 자식 노드를 리턴합니다.
- lastChild : 자식 노드 중, 마지막 자식 노드를 리턴합니다.
형제(sibling) 노드 탐색
- previousSibling : 같은 레벨의 노드 중, 이전 노드를 리턴합니다.
- nextSibling : 같은 레벨의 노드 중, 다음 노드를 리턴합니다.
리스트 삭제 기능
// 리스트 추가
const addItem = (text) => {
if (text) {
const li = document.createElement("li");
...
span.innerText = text;
button.innerText = "삭제";
// 삭제버튼 클릭시 해당 요소의 리스트 삭제
button.addEventListener("click", delItem);
// 요소추가
div.append(checkbox, span);
li.append(div, button);
ul.appendChild(li);
}
};- 완료 여부 기능과 마찬가지로 리스트에 추가할 때마다 추가된 리스트에는 리스트 삭제 기능이 작동되어야 되기 때문에 추가 부분에 이벤트 작성
// 리스트 삭제
const delItem = (e) => {
// 삭제버튼의 부모요소를 찾아오고 그 요소를 삭제해야 된다.
const target = e.target.parentElement; // 지워야하는 리스트 요소
target.remove();
};- 삭제버튼 클릭 시 li를 삭제해야 되기 때문에 삭제버튼의 부모요소를 찾아와서 그 요소를 삭제해야 된다.
- remove를 사용하여 해당 요소를 삭제해 준다.
참고자료
https://www.youtube.com/watch?v=aV7SCTz5DgM
https://www.youtube.com/watch?v=Dkexm65Ozz0
https://hianna.tistory.com/712
[Javascript] 부모, 자식, 형제 노드(node)와 요소(element) 찾기
지난번에는 node와 element의 차이에 대해서 정리해보았습니다. 이번에는 dom에서 부모, 자식, 형제 노드(node)와 요소(element)를 탐색하는 방법을 정리해 보도록 하겠습니다. node 탐색 부모(parent) 노드
hianna.tistory.com