사전 캠프/달리기반 과제 모음

할 일 목록(To Do List) 만들기 (2)

Iruka913 2024. 9. 13. 17:44

오늘 배운 것들.

제이퀴리를 이용해선 appendChild를 쓸 수가 없다고 한다.

 

튜터님 왈, 제이퀴리는 일종의 지름길. 자바 스크립트에 대한 이해를 위해서는 자바 스크립트 원어로 웬만해선 코딩하는 게 낫다고 하신다. 

 

완성된 코드를 바탕으로, 하나하나씩 오늘 배운 걸 살펴보도록 하자. 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
        integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <title>To-do 리스트</title>

    <style>
        .box {
            width: 300px;
            height: 350px;
            margin: 300px auto 0px auto;
            display: flex;
            flex-direction: row;
            align-items: center;
            justify-content: center;

            border: 1px solid black;
            border-radius: 5px;
            box-shadow: 0px 0px 3px 0px black;
        }

        .btn {
            width: 80px;
            height: 40px;

            border: 1px solid black;
            border-radius: 5px;
            box-shadow: 0px 0px 3px 0px black;
        }
    </style>
</head>

<body>
    <div class="box">
        <div id="content" class="content">
            <h1>투두 리스트</h1>
            <input type id="inputlist" placeholder="할 일을 입력하세요">
            <button id="addbtn" class="btn">추가</button>

            <div id="addedlists" class="form-check">
            </div>
        </div>

        <script>
            document.addEventListener('DOMContentLoaded', () => { // 시.... 작!

                let inputlist = document.getElementById('inputlist')
                let addbtn = document.getElementById('addbtn')
                let content = document.getElementById('content')

                addbtn.addEventListener('click', function () { // 할 일을 추가하는 함수 시작.
                    let list = $('#inputlist').val()
                    console.log(list)

                    // 1. <div id="addedlists" class="form-check"> 생성
                    let div = document.createElement('div');
                    div.id = 'addedlists';           // id 설정
                    div.classList.add('form-check');  // 클래스 추가

                    // 2. <input class="form-check-input" type="checkbox" value="" id="flexCheckDefault"> 생성
                    let checkbox = document.createElement('input');
                    checkbox.type = 'checkbox';        // type 설정
                    checkbox.classList.add('form-check-input');  // 클래스 추가
                    checkbox.id = 'flexCheckDefault';  // id 설정

                    // 3. <label class="form-check-label" for="flexCheckDefault"> 생성
                    let label = document.createElement('label');
                    label.classList.add('form-check-label');  // 클래스 추가
                    label.setAttribute('for', 'flexCheckDefault');  // for 속성 설정
                    label.innerText = list;  // 라벨 텍스트 설정

                    // 4. <button id="deletebtn">삭제.</button> 생성
                    let button = document.createElement('button');
                    button.classList.add('deletebtn');          // id 설정
                    button.innerText = '삭제.';        // 버튼 텍스트 설정

                    // 5. 각 요소를 <div>에 추가
                    div.appendChild(checkbox);  // checkbox 추가
                    div.appendChild(label);     // label 추가
                    div.appendChild(button);    // button 추가

                    // 6. <div>를 원하는 위치에 추가 (예: content라는 id를 가진 곳에 추가)
                    document.getElementById('content').appendChild(div)

                    checkbox.addEventListener('change', (event) => { // 체크박스가 체크되면 취소줄
                        if (event.currentTarget.checked) {
                            label.style.textDecoration='line-through'
                        } else {
                            label.style.textDecoration='none'
                        }
                    })
                    button.addEventListener('click', function () { // 버튼이 눌리면 삭제.
                        content.removeChild(div);
                    });


                }) // 여기까지 버튼이 눌리면 생성되는 함수
            })
        </script>
</body>

</html>

 

완성!

기능 일람. 

무언가를 입력하면 하단에 리스트를 출력한다. 

체크 박스를 체크하면, 취소줄이 그어진다.

삭제 버튼을 누르면 해당 리스트가 삭제된다. 

document.addEventListener('DOMContentLoaded', () => { }// 시.... 작!

이 함수는 페이지가 시작되면 곧장 발동되는 효과를 가지고 있다. 

                let inputlist = document.getElementById('inputlist')
                let addbtn = document.getElementById('addbtn')
                let content = document.getElementById('content')

각각의 아이디를 가지고 와, 변수에 저장하였다. 

제이퀴리를 통해서 간단히 나타낼 수 있지만, 되도록 자바 스크립트로 표현해보도록 하자. 

addbtn.addEventListener('click', function () { // 할 일을 추가하는 함수 시작.
                    let list = $('#inputlist').val() // list에 인풋으로 받아온 데이터 저장.
                    console.log(list)

                    // 1. <div id="addedlists" class="form-check"> 생성
                    let div = document.createElement('div');
                    div.id = 'addedlists';           // id 설정
                    div.classList.add('form-check');  // 클래스 추가

                    // 2. <input class="form-check-input" type="checkbox" value="" id="flexCheckDefault"> 생성
                    let checkbox = document.createElement('input');
                    checkbox.type = 'checkbox';        // type 설정
                    checkbox.classList.add('form-check-input');  // 클래스 추가
                    checkbox.id = 'flexCheckDefault';  // id 설정

                    // 3. <label class="form-check-label" for="flexCheckDefault"> 생성
                    let label = document.createElement('label');
                    label.classList.add('form-check-label');  // 클래스 추가
                    label.setAttribute('for', 'flexCheckDefault');  // for 속성 설정
                    label.innerText = list;  // 라벨 텍스트 설정

                    // 4. <button id="deletebtn">삭제.</button> 생성
                    let button = document.createElement('button');
                    button.classList.add('deletebtn');          // id 설정
                    button.innerText = '삭제.';        // 버튼 텍스트 설정

                    // 5. 각 요소를 <div>에 추가
                    div.appendChild(checkbox);  // checkbox 추가
                    div.appendChild(label);     // label 추가
                    div.appendChild(button);    // button 추가

                    // 6. <div>를 원하는 위치에 추가 (예: content라는 id를 가진 곳에 추가)
                    document.getElementById('content').appendChild(div)

 

길지만 차근차근 뜯어보자면, 이건 부트스트랩에서 가져온 템플릿을 그대로 생성하는 과정이라고 할 수 있다. 

id는 중복으로 만들 수 없어서 특정 id를 지목하려 할 때, 오류가 터질 수 있다.

 

이렇게 특정 html을 여러 개 생성할 때는 classlist.add를 사용하여 클래스를 추가하여 id를 중복 부여 하는 일을 피할 수 있다. (사실 따지고 보면, 위에 아이디 설정 같은 건 필요 없을 지도 모른다. 나중에 다시 이런 걸 시도할 때가 오면, 아이디 부여 없이 한 번 만들어보자.)

 

과정을 살펴보면, div라는 변수 안에 <div> 태그를 만든 뒤, 그 안에 요소들을 하나하나 만든 뒤, 마지막에 블록처럼 하나하나 끼워넣는 방식이라는 걸 알 수 있다. 서식만 안다면, 금방 따라할 수 있을 듯 하다! 

 

마지막에는 content 아이디에 지금 만든 div를 appendChild로 부여했다. 이렇게 하면 부트스트랩의 체크박스를 그대로 가져와서 무한히 찍어낼 수가 있다. 

 

checkbox.addEventListener('change', (event) => { // 체크박스가 체크되면 취소줄
                        if (event.currentTarget.checked) {
                            label.style.textDecoration='line-through'
                        } else {
                            label.style.textDecoration='none'
                        }
                    })

 

앞서 만든 checkbox 변수에 이벤트 리스터를 추가. 이게 '바뀔 시' 무언가 벌어진다는 걸 표현하고 있다. 

만약 event.currentTarget.checked 즉 현재 대상이 체크 되었을 경우, 취소줄이 그어진다는 걸 표현하고 있다. 

그렇지 않을 시에는 아무것도 하지 않는다, 라는 뜻을 내포하고 있다. 

button.addEventListener('click', function () { // 버튼이 눌리면 삭제.
                        content.removeChild(div);
                    });

 

이번에는 버튼 변수에다가 이벤트 리스너를 추가해, 버튼이 클릭되면 div에 생성된 Child를 삭제하는 방향으로 코드가 짜여져 있다. 

 

그렇게 해서 투두 리스트가 완성되었다!