하고 싶은 일
1. 할 일을 입력 받음
2. 리스트에 올라감
3. 리스트의 테두리에 박스가 있었으면 좋겠음
4. 리스트의 마커가 체크박스였으면 좋겠음
5. 체크박스가 checked 상태일 때 취소선이 생김
6. 목록에 있는 할일을 삭제할 수 있는 기능이 있었으면 좋겠음
7. html 파일과 js 파일이 나눠졌으면 좋겠음(refactoring)
목록의 요소 삭제하기
[취소선 만들기]에서 썼던 addEventListener()를 사용해서 delItem이라는 함수로 목록의 요소를 삭제할 수 있도록 했다.
1. function.bind(thisArg, arg1, arg2, ···)
bind 매서드를 사용하면, 함수의 컨텍스트를 변경하거나, 함수에 초기 인수를 설정하는 등의 작업을 할 수 있다.
여기에서 function은 delItem이 되고,
thisArg에는 null을 넣어서 this 값을 무시하고 사용할 수 있도록 했고,
arg1에 i를 넣어서 항목의 해당 인덱스를 함수에 전달할 수 있도록 해서 삭제 기능이 동작할 수 있도록 했다.
추가한 코드는 아래와 같다.
var del = document.createElement("button"); //삭제 버튼
todoItem.appendChild(del);
del.innerText = "X";
del.addEventListener("click", delItem.bind(null, i));
function delItem(index) {
var listItem = list.children[index];
// console.log(listItem);
listItem.remove();
todolist.splice(index, 1);
}
2. 수정 사항
' 체크 박스에 체크를 하고 새로운 항목을 추가하면 체크가 유지되지 않음 ' 오류가 발생하여 이를 해결하기 위해 상태를 유지하기 위한 코드를 추가했다.
if (todolist[i].deleted) {
span.style.textDecoration = "line-through";
checkbox.checked = true;
}
uploadTodoList 함수가 실행될 때마다 체크박스들이 다시 생성되면서 발생하는 문제임을 알게 되었다.
따라서 기존에 생성한 체크박스들은 유지를 하고, 새로운 항목을 추가할 때는 새로운 체크박스를 생성하지 않도록 코드를 수정했다.
3. 전체 코드
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Todo-List</title>
<style>
#wholeList {
background-color: powderblue;
padding: 5px;
border: 2px solid lightgray;
margin-left: 500px;
margin-right: 500px;
margin-top: 5px;
padding-bottom: 5px;
}
#input {
border-top: 1px solid lightgray;
padding-top: 5px;
margin-bottom: 0px;
}
#list {
display: inline-block;
text-align: left;
padding: 5px 0px 5px 5px;
margin-bottom: 5px;
font-size: 24px;
}
body {
text-align: center;
}
ul {
list-style-type: none;
}
</style>
<script>
var todolist = [];
function uploadTodoList() {
var enrollText = document.getElementById("enrollText");
var list = document.getElementById("list");
var txt = enrollText.value;
todolist.push({ text: txt, deleted: false });
enrollText.value = null;
list.innerHTML = "";
for (var i = 0; i < todolist.length; i++) {
var todoItem = document.createElement("li");
var checkbox = document.createElement("input"); //체크박스
var span = document.createElement("span"); // 글자
checkbox.type = "checkbox";
span.appendChild(document.createTextNode(todolist[i].text));
todoItem.appendChild(checkbox);
todoItem.appendChild(span);
list.appendChild(todoItem);
// X 버튼 만들기
var del = document.createElement("button"); //삭제 버튼
todoItem.appendChild(del);
del.innerText = "X";
console.log(list);
if (todolist[i].deleted) {
span.style.textDecoration = "line-through";
checkbox.checked = true;
}
checkbox.addEventListener("change", doneTodo(i));
del.addEventListener("click", delItem.bind(null, i));
}
function doneTodo(index) {
return function () {
var todo = todolist[index];
todo.deleted = this.checked;
var span = this.parentElement.querySelector("span");
if (todo.deleted) {
span.style.textDecoration = "line-through";
} else {
span.style.textDecoration = "none";
}
};
}
function delItem(index) {
var listItem = list.children[index];
// console.log(listItem);
listItem.remove();
todolist.splice(index, 1);
}
}
</script>
</head>
<body>
<h1>To-Do List</h1>
<div id="wholeList">
<ul id="list"></ul>
<!-- 할일 입력하기 -->
<div id="input">
<input id="enrollText" type="text" />
<input
type="button"
value="등록"
onclick="
uploadTodoList();
alert('등록 완료!');
"
/>
</div>
</div>
</body>
</html>
'Front-End' 카테고리의 다른 글
[React] 컴포넌트 만들기(사용자 정의 태그) (0) | 2023.08.16 |
---|---|
[React] 기초 환경 세팅, 코드 수정, 배포 (0) | 2023.08.14 |
[JavaScript] To-do List 만들기 - 2 (취소선 만들기) (0) | 2023.08.07 |
[JavaScript] To-do List 만들기 - 1 (박스 만들기, list의 marker로 checkbox 사용) (0) | 2023.07.01 |
[JavaScript] 객체와 메소드와 반복문 (0) | 2023.06.28 |