05. 속성 노드 조작 방법

양희준·2022년 3월 6일
0

DOM

목록 보기
5/8
post-thumbnail

📌 5-1 속성 노드란?

HTML의 속성을 가리킨다. DOM의 프로퍼티에도 해당이 된다.

💡 요소 노드를 통해서 접근이 가능하다.
💡 속성 노드는 부모 노드가 존재하지 않는다.

📌 5-2 요소 노드의 속성 노드 조작방법

🧩 Element.prototype.getAttribute(attributeName)
✔ 속성 노드의 값 접근

🧩 Element.prototype.setAttribute(attributeName, value)
✔ 속성 노드의 값을 수정

🧩 Element.prototype.removeAttribute(attributeName)
✔ 속성 노드의 값을 삭제

🧩 Elemnet.prototype.hasAttribute(attributeName)
✔ 속성 노드의 값이 존재하는지 확인

<!DOCTYPE html>
<html lang="kr">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <input id="input" type="text" value="Default"> <br/> <br/>
        <button type="button">console.log</button>
    </body>
    <script>
        const $input = document.querySelector("#input");
        const $btn = document.querySelector("button");
        // 순차적으로 실행하기 위해서 제너레이터 사용
        const step = function * () {
            // value 속성 노드의 값을 가져온다.
            yield $input.getAttribute("value");
            // value 속성 노드의 값을 수정한다.
            $input.setAttribute("value", "Change");
            // value 속성 노드의 값을 가져온다
            yield $input.getAttribute("value");
            // value 속성 노드를 제거한다.
            $input.removeAttribute("value");
            // input 요소 노드의 속성 노드에 value가 있는지 확인한다.
            yield $input.hasAttribute("value");
        }();
        $btn.addEventListener("click", () => {
            const check = step.next();
            // 오류 방지
            if(check.done) return;
            else console.log(check.value);
        });
    </script>
</html>

📌 5-3 HTML 속성과 DOM의 프로퍼티

✔ HTML 속성은 초기의 속성 노드의 값에 대응한다. 처음에 HTML 태그안에 적은 속성값을 가지고 있다. 초기값의 접근 하는 방법은 getAttribute() 메소드를 이용해서 값에 접근하거나 setAttribute()로 초기값을 수정하는 방법이 있다.
✔ DOM의 프로퍼티는 사용자가 인터페이스를 이용해서 바꾼 최신상태의 값을 가지고 있다.

<!DOCTYPE html>
<html lang="kr">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <input id="input" type="text" value="Default"> <br/> <br/>
        <button id="default" type="button">Default</button>
        <button id="change" type="button">Change</button>
    </body>
    <script>
        const $input = document.querySelector("#input");
        const $default = document.querySelector("#default");
        const $change = document.querySelector("#change");
        // HTML의 속성으로 접근
        $default.addEventListener("click", () => {
            // input을 변경해도 HTML 태그 안에 있는 초기값을 가지고 있다.
            console.log($input.getAttribute("value"));
        });
        //DOM 프로퍼티로 접근
        $change.addEventListener("click", () => {
            // 현재 최신값으로 변경된다.
            console.log($input.value);
        });
    </script>
</html>

🔥 DOM의 프로퍼티로 접근하는 방법은 직접 요소 노드의 속성 노드의 이름을 객체 프로퍼티로 접근한다.
🔥 HTML의 속성으로 접근하는 방법은 메소드를 이용해 접근한다.

📌 5-4 요소노드의 data

생성 방법 : 해당 요소 노드에 속성 노드를 추가 형식은 data-string 형태
접근 방법 : 해당 요소 노드에 접근하여 객체 프로퍼티(dataset)로 접근 카멜표기법 준수

<!DOCTYPE html>
<html lang="kr">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <ul id="list">
            <!-- 생성 -->
            <li data-animals-index="0">Cat</li>
        </ul>
    </body>
    <script>
        const $li = document.querySelector("li");
        // 접근 방법 결과 : "0";
        console.log($li.dataset.animalsIndex);
    </script>
</html>
<!DOCTYPE html>
<html lang="kr">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <ul id="list">
            <li data-animals-index="0">Cat</li>
            <li>Dog</li>
        </ul>
    </body>
    <script>
        const $li = document.querySelectorAll("li");
        const [$cat, $dog] = $li;
        // 이런식으로 접근도 가능하다.
        $dog.setAttribute("data-animals-index", "1");
        // 결과 : "1"
        console.log($dog.dataset.animalsIndex);
    </script>
</html>

📌 5-5 요소 노드의 data로 CRUD 구현

보통사용 방법은 해당 요소 노드의 인덱스를 제공하여 이벤트 위임을 사용하여 해당 요소 노드를 체크하고 CRUD에 이용한다.

<!DOCTYPE html>
<html lang="kr">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <input id="input" type="text"> <br/> <br/> 
        <button id="add">추가</button> <br/>
        <ul id="list">
        </ul>
    </body>
    <script>
        // 동물의 이름을 입력 받아 저장할 배열 선언
        const animals = [];
        // input의 동물의 이름을 전송하기 위해 버튼 요소 접근
        const $addbtn = document.querySelector("#add");
        // 이벤트 위임을 위해서 id가 list인 요소에 접근
        const $list = document.querySelector("#list");
        // 페이지를 계속 고쳐줄 함수 생성
        const render = () => {
            // animals의 이름을 받아서 HTML요소로 바꾸기
            const makeHTML = animals.map((item, index) => {
                // index를 받아서 data에 index로 사용하기 위해 지정
                return `<div data-animals-index=${index} style="display: flex">
                    <li>${item}</li>
                    <button id="update" style="margin-left: 10px">수정</button>
                    <button id="remove" style="margin-left: 10px">삭제</button>
                </div>`
            });
            // 해당 배열 내용을 문자열로 치환후 HTML 조작
            $list.innerHTML = makeHTML.join('');
        }
        $addbtn.addEventListener("click", () => {
            // input 요소에 접근
            const $input = document.querySelector("#input");
            // animals 배열에 해당 동물을 저장
            animals.push($input.value);
            // input 초기화
            $input.value = null;
            // 페이지 수정
            render();
        });
        // 이벤트 위임
        $list.addEventListener("click", (e) => {
            // 해당 동물의 인덱스 번호를 이벤트를 위임해논 요소의 dataset에 접근 
            const index = e.target.closest("div").dataset.animalsIndex;
            // 클릭한 요소가 id가 update 버튼인지 확인
            if(e.target.id === "update") {
                // 수정받는 값을 변수에 저장
                const updateText = prompt("수정할 동물의 이름을 입력하세요.");
                // 해당 배열인덱스에 접근하여  값 수정
                animals[index] = updateText;
                // 페이지 수정
                render();
            // 클릭한 요소가 id가 remove 버튼인지 확인
            } else if(e.target.id === 'remove') {
                // 해당 배열에서 요소 삭제
                animals.splice(index, 1);
                // 페이지 수정
                render();
            }
        });
    </script>
</html>

🔥 Element.prototype.closest(tagName)는 처음으로 만난 해당 태그의 부모노드를 반환한다.
🔥 이벤트 위임과 e.target은 이벤트 부분에서 확인하기

<!DOCTYPE html>
<!-- innerHTML XSS 단점으로 노드의 상속을 이용해서 만든 코드 -->
<html lang="kr">
    <head>
        <meta charset="UTF-8">
    </head>
    <style>
        .form {
            display: flex;
        }
        .blank {
            margin-left: 10px;
        }
    </style>
    <body>
        <input id="input" type="text"> <br/> <br/> 
        <button id="add">추가</button> <br/>
        <ul id="list">
        </ul>
    </body>
    <script>
        const animals = [];
        const $addbtn = document.querySelector("#add");
        const $list = document.querySelector("#list");
        // 노드의 자식들을 모두 지워주기 위해서 reset 함수 생성
        const reset = () => {
            // childeNodes는 라이브객체이므로 배열로 바꿔서 사용
            const child = [...$list.childNodes];
            // 해당 자식 요소 노드 전부 삭제
            child.forEach((item) => item.remove());
        }
        // 페이지를 새로 고쳐줄 함수
        const render = () => {
            // 페이지를 고치기 전에 reset함수 실행
            reset();
            // 의미없는 태그인 div를 한번더 생성하지 않기 위해 생성
            const $container = document.createDocumentFragment();
            // 해당 배열의 요소마다 실행할 코드
            animals.forEach((item, index) => {
                // 노드 생성 하고 속성 생성 클래스이름 생성으로 CSS 적용
                const $div = document.createElement("div");
                const $li = document.createElement("li");
                const $updateBtn = document.createElement("button");
                const $removeBtn = document.createElement("button");
                $updateBtn.id = "update";
                $updateBtn.className = "blank";
                $updateBtn.innerText = "수정";
                $removeBtn.id = "remove";
                $removeBtn.className = "blank";
                $removeBtn.innerText = "삭제";
                $li.innerText = item;
                $div.className = "form";
                $div.setAttribute("data-animals-index", index);
                // 상속 코드
                $div.appendChild($li);
                $div.appendChild($updateBtn);
                $div.appendChild($removeBtn);
                $container.appendChild($div);
            });
            // ul 태그에 추가
            $list.appendChild($container);
        }
        $addbtn.addEventListener("click", () => {
            const $input = document.querySelector("#input");
            animals.push($input.value);
            $input.value = null;
            render();
        });
        $list.addEventListener("click", (e) => {
            const index = e.target.closest("div").dataset.animalsIndex;
            if(e.target.id === "update") {
                const updateText = prompt("수정할 동물의 이름을 입력하세요.");
                animals[index] = updateText;
                render();
            } else if(e.target.id === 'remove') {
                animals.splice(index, 1);
                render();
            }
        });
    </script>
</html>
profile
JS 코린이

0개의 댓글