기초공사 (html,css,javascript)

07_DOM활용하기2 (예제로 노드추가, 삭제) 본문

javascript/js_study

07_DOM활용하기2 (예제로 노드추가, 삭제)

에스프레소라떼 2023. 6. 6. 20:34

1.Book List 만들기

[저장하기]버튼을 클릭하면  '제목'과 '저자'필드에 입력된 내용을 가져와서 bookList영역에 <li> 태그와 함께 추가하자.

텍스트 필드 내용은 title.value처럼 텍스트 필드 요소의 이름 뒤에 .value를 붙여서 가져올 수 있다.

 

//html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<div id = "container">
    <h1>Book List</h1>
    <form>
        <ul id="bookInfo">
            <li>
                <label for="title">제목</label>
                <input type="text" id="title" >
            </li>
            <li>
                <label for="author">저자</label>
                <input type="text" id="author" >
            </li>
        </ul>

        <button type="reset">취소하기</button>
        <button id="save">저장하기</button>
    </form>

    <ul id ="bookList"></ul>
</div>

<script src="js/bookList.js"></script>
</body>
</html>

// js

/*
1. '저장하기'버튼을 클릭하면 제목,저자쓴것이 bookList에 표시가 되고,
ul인거보니 li가 생길것이므로 li를 추가하는 요소노드를 입력하자.
: 제목,저자 쓴것을 가져온다.--> 변수로 지정
:저장해야 하므로 --> 변수 지정

2. '취소하기' 버튼을 클릭하면 삭제된다.
*/

/*
생각노트 -클릭하면 뭐가와야해? 제목,저자 입력값을 가져와야한다.
title.value에서 처음생각에 value가 생각이 안날땐 input이라고 검색한 후 input에 넣을 프로퍼티를 찾아보자..
찾아보니 value를 입력해야 네모칸 안에 입력할수있다.

creatElement("li") //요소노드만든다.

이제 텍스트노드를 만들어야 하는데 이건 어디서 만들어져?
title.value와 author.value에서 만들어진다.

*/

const title = document.querySelector("#title");
const author = document.querySelector("#author");
const save = document.querySelector("#save");
const bookList = document.querySelector("#bookList");

console.dir(title);

save.addEventListener('click', (e) => {
    e.preventDefault();
    //1. 요소노드를 만든다.
    const item = document.createElement("li");
    
    console.dir(item);
    
    //2. li에 넣을 텍스트노드를 만든다. input에 입력한 값을 가져와야한다.
    (새로운텍스트노드를 가져올떄 textNode를 쓰는건가)
    // let textNode = document.createTextNode("title.value"); //디버깅하니 입력한 값이 나와야하는데 text로 뜬따.왜??
    // let textNode_auth = document.createTextNode("author.value")
    
    let textNode = title.value;  //위에 처럼 하다가 안되서 이렇게 수저하니 된다.
    let textNode_auth = author.value;

    console.log(textNode); //title.value의 값이 보여진다.
    console.log(textNode_auth); //author.value의 값이 보여진다.-->화면에 보여지면된다.

    //item.innerText = `${textNode} - ${textNode_auth}`;  //삭제버튼을 만들 수 없다.
    item.innerHTML = `${textNode} - ${textNode_auth}
    <span class="delButton">삭제</span>`;

    /*3.두개를 연결한다. --연결 안되도 왜 나오지?;;
    텍스트노드처럼 입력한 값을 가져와야 할 경우는 이미 html에 있기때문에 연결안해도 된다.
    나의 생각 이해안되면.07_insert.html을 참고할것.
        item.appendChild(textNode);
        item.appendChild(textNode_auth);
    */
   
    //4. 화면에 보여지게 한다.
    bookList.appendChild(item)

    title.value = "";
    author.value = "";

    // 삭제 되게하기! 삭제버튼 span을 삭제하는것이 아니라 그 안에 li를 삭제하는것
    //내가 선택한 this의 부모노드를 찾아서 자식노드를 삭제한다.

    const delButtons = document.querySelectorAll(".delButton") //삭제버튼 요소를 모두 가져온다.

    for(let delButton of delButtons){
        delButton.addEventListener('click', function(){
            //this.parentNode.remove(this); li를 사라지면되는데 remove(this)에서 this는 삭제버튼이다.
            this.parentNode.parentNode.removeChild(this.parentNode);
        });
    }
});

 

삭제하기

remove( ) 메서드 사용하기
: 삭제하려는 요소에서 사용하는 메서드이다.
메서드를 사용한 노드 자체를 삭제한다.
요소.remove( )
removeChild( ) 메서드 사용하기

: 현재요소보다 하위요소, 즉 자식 노드를 삭제해야할 경우는 이 메서드를 사용한다.

li의 자식인 요소를 삭제해야한다면 말이다.

그러기 위해선 부모 노드를 찾은 후에 자식 노드를 삭제한다.

 this.parentNode.parentNode.removeChild(this.parentNode);

해석;

this는 여기에서 삭제 버튼이다.

삭제버튼의 부모의 부모, 즉 여기서는 ul을 의미한다.

removeChild(this.parentNode)

--> 삭제버튼의 부모인 li를 삭제 한다는 뜻

 

this를 사용할 때 주의할 점

화살표 함수에서는 this는 window객체를 가리킨다.

window 객체는 DOM의 최상위 객체이므로 클릭한 대상을 this라는 예약어로 사용하려면 화살표함수가 아닌

익명함수형식으로 지정해야 한다. 매우 중요하므로 꼭 기억!

 

더보기

나중에 도움 될 수 있으니 이해 안됐던 코드 디버깅 하는 화면 

아직 어떻게 가져온지 몰라서 디버깅을 많이 하다 얻어걸린다.

 

부모를 지정해주는게 아니라 부모의 부모를 지정해줘야함을 알려주는 디버깅~