03. DOM 조작 방법

양희준·2022년 2월 20일
0

DOM

목록 보기
3/8
post-thumbnail

📌 3-1 DOM 조작 방법이란?

웹 브라우저에서 렌더링 할 HTML 문서를 변경이나 수정하는 방법

💡 HTML처럼 문자열로 입력하여 조작이 가능하다.
💡 노드를 생성해서 추가하거나 삭제 변경 등등 DOM Tree 조작이 가능하다.

📌 3-2 DOM HTML 조작

🧩 Element.prototype.innerHTML

✔ 구현이 간단하고 코드가 직관적이다.
✔ HTML의 데이터를 문자열로 직접 입력하기 때문에 XSS에 취약하다.

<!DOCTYPE html>
<html lang="kr">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <div id="title"></div>
    </body>
    <script>
        const $div = document.querySelector("#title");
        // 자식노드로 추가된다. 직접 코드를 작성해서 직관적
        $div.innerHTML = `<h2>Hello</h2>`
        // 결과 <div id="title> <h2>Hello</h2> </div>
        console.log($div);
    </script>
</html>

🧩 Element.prototype.insertAdjacentHTML(position, HTML string)

✔ 구현이 간단하고 형제노드로도 추가가 가능하며 코드가 직관적이다.
✔ HTML의 데이터를 문자열로 직접 입력하기 때문에 XSS에 취약하다.

<!DOCTYPE html>
<html lang="kr">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <div id="title"></div>
    </body>
    <script>
        const $div = document.querySelector("#title");
        // 자식노드로 추가
        $div.insertAdjacentHTML("afterbegin", `<h2>Title</h2>`);
        // 형제노드로 추가
        $div.insertAdjacentHTML("afterend", `<div id="subtitle">Subtitle<div>`);
        // body 태그 결과확인
        console.log(document.body);
    </script>
</html>

📃 되도록이면 HTML 조작방식보다 노드를 생성해서 자식노드로 추가하여 사용을 권장하고 있다.

📌 3-3 노드 생성

🧩 Document.prototype.createElement(tagName)
🧩 Document.prototype.createTextNode(text)

<!DOCTYPE html>
<html lang="kr">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <!--DOM 조작-->
    </body>
    <script>
        // div 태그 생성
        const $div = document.createElement("div");
        // 텍스트 노드 생성
        const $divText = document.createTextNode("Hello");
        // 텍스트 노드는 무조건 요소 노드의 자식이므로 자식노드로 넘겨줌
        $div.appendChild($divText);
        // body 태그에 직접 자식으로 상속
        document.body.appendChild($div);
        // 결과 : <body>...</body>
        console.log(document.body);
    </script>
</html>

📌 3-4 노드 삽입

🧩 Node.prototype.appendChild(node)
🧩 Node.prototype.insertBefore(newNode, referenceNode)

✔ appendChild는 무조건 마지막 자식노드로 위치하게 된다.
✔ insertBefore는 기준점 노드 앞에 위치하게 된다 기준점 노드에 null을 넣는 경우 맨뒤에 추가.

<!DOCTYPE html>
<html lang="kr">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <div id="title"></div>
        <div id="content"></div>
    </body>
    <script>
        const $title = document.querySelector("#title");
        const $content = document.querySelector("#content");
        const $span = document.createElement("span");
        $span.innerText = "Top";
        $title.appendChild($span);
        const $div = document.createElement("div");
        $div.innerText = "Mid";
        $content.innerText = "Bottom";
        // document.body.insertBefore($div, null); 
        document.body.insertBefore($div, $content);
        // 결과 : <body>...</body>
        console.log(document.body);
    </script>
</html>

📌 3-5 노드 교체

🧩 Node.prototype.replaceChild(newNode, referenceNode)

<!DOCTYPE html>
<html lang="kr">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <div id="title">Title</div>
        <div id="content">Content</div>
    </body>
    <script>
        // id가 content인 요소 노드에 접근
        const $content = document.querySelector("#content");
        // div 요소 노드 생성
        const $subtitle = document.createElement("div");
        // 텍스트 노드를 Subtitle로 생성
        $subtitle.innerText = "Subtitle";
        // 노드 교체
        document.body.replaceChild($subtitle, $content);
    </script>
</html>

📌 3-6 노드 삭제

🧩 Element.prototype.remove()
🧩 Node.prototype.removeChild(node)

✔ remove 메소드는 요소 노드와 해당 자식 노드까지 제거
✔ removeChild 메소드는 자식 노드만 제거

<!DOCTYPE html>
<!-- 요소 노드는 라이브 객체이기 때문에 버튼을 눌러 console에서 확인후 다시 누르기 -->
<html lang="kr">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <div id="title">Title</div>
        <div id="content">Content</div> <br />
        <button id="btn" type="button">console.log</button>
    </body>
    <script>
        const $title = document.querySelector("#title");
        const $content = document.querySelector("#content");
        const $btn = document.querySelector("#btn");
        // removeChild를 사용하여 텍스트 노드를 제거하는 함수
        const removeContentText = () => {
            const [ textNode ] = $content.childNodes;
            // 자식의 요소만 삭제가 가능하다.
            $content.removeChild(textNode);
            console.log(document.body);
            return;
        }
        // remove를 사용하여 요소 노드와 요소 노드의 자식까지 제거
        const removeTitle = () => {
            // 해당 요소 노드와 자식 노드까지 제거
            $title.remove();
            console.log(document.body);
        };
        // 순차적으로 실행하기 위해서 제너레이터 사용
        const step = function * () {
            yield removeTitle();
            yield removeContentText();
        }();
        $btn.addEventListener("click", () => {
            const check = step.next();
            // 오류 방지
            if(check.done) return;
        });
    </script>
</html>

📌 3-7 노드 복사

🧩 Node.prototype.cloneNode([ deep : true | false ])

✔ default 값은 false 이다. 인자에 아무것도 없이 사용하면 기본값 적용
✔ true이면 깊은 복사를 진행한다.

<!DOCTYPE html>
<html lang="kr">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <!--자식노드부터 2 Depth 시작 텍스트 노드도 자식노드에 포함된다.-->
        <div id="title"> Hello
            <span>World</span>
        </div>
    </body>
    <script>
        const $title = document.querySelector("#title");
        // 얇은 복사 $title.cloneNode(false)랑 표현이 같다.
        const shallowCopy = $title.cloneNode(); 
        // 깊은 복사
        const deepCopy = $title.cloneNode(true);
        // 결과 : <div id="title"></div> 요소 노드만 복사
        console.log(shallowCopy);
        // 결과 : <div id="title">...</div> 요소 안에 있는 자식노드도 모두 복사
        console.log(deepCopy);
    </script>
</html>
profile
JS 코린이

0개의 댓글