본문 바로가기
프로그래밍언어/JavaScrpit

[모던 자바스크립트 Deep Dive] 39장 DOM(2)

by qkzkdo 2024. 2. 17.
728x90

39.4 노드 정보 취득

노드 객체에 대한 정보 취득 프로퍼티

  • Node.prototype.nodeType
  • Node.protytype.nodeName

 

 

39.5 요소 노드의 텍스트 조작

39.5.1 nodeValue

지금까지 살펴본 토드 탐색, 노드 정보 프로퍼티는 모두 읽기 전용 접근자 프로퍼티다. 지금부터 살펴볼 Node.prototype.nodeValue 프로퍼티는 setter와 getter 모두 존재하는 접근자 프로퍼티다.

 

노드 객체의 nodeValue 프로퍼티를 참조하면 노드 객체의 값을 반환한다. 노드 객체의 값이란 텍스트 노드의 텍스트다.

 

39.5.2 textContent

Node.prototype.textContent 프로퍼티는 setter와 getter 모두 존재하는 접근자 프로퍼티로서 요소 노드의 텍스트와 모든 자손 노드의 텍스트를 모두 취득하거나 변경한다.

 

 

39.6 DOM 조작

DOM 조작DOM manipulation은 새로운 노드를 생성하여 DOM에 추가하거나 기존 노드를 삭제 또는 교체하는 것을 말한다.

 

39.6.1 innerHTML

Element.prototype.innerHTML 프로퍼티는 setter와 getter 모두 존재하는 접근자 프로퍼티로서 요소 노드의 HTML 마크업을 취득하거나 변경한다.

 사용자로부터 입력받은 데이터를 그대로 innterHTML 프로퍼티에 할당하는 것은 크로스 사이트 스크립팅 공격XSS에 취약하므로 위험하다. HTML 마크업 내에 자바스크립트 악성 코드가 포함되어 있다면 파싱 과정에서 그대로 실현될 가능성이 있기 때문이다.

 

innterHTML 프로퍼티의 또 다른 단점은 요소 노드의 innterHTML 프로퍼티에 HTML 마크업 문자열을 할당하는 경우 요소 노드의 모든 자식 노드를 제거하고 할당한 HTML 마크업 문자열을 파싱하여 DOM을 변경한다는 것이다.

 

innterHTML 프로퍼티는 새로운 요소를 삽입할 때 삽입될 위치를 지정할 수 없다는 단점도 있다.

 

39.6.2 insertAdjacentHTML 메서드

Element.prototype.insertAdjacentHTML(position, DOMString) 메서드는 기존 요소를 제거하지 않으면서 위치를 지정해 새로운 요소를 삽입한다.

insertAdjacentHTML 메서드는 두 번째 인수로 전달한 HTML 마크업 문자열(DOMString)을 파싱하고 그 결과로 생성된 노드를 첫 번째 인수로 전달한 위치(position)에 삽입하여 DOM에 반영한다. 

 

39.6.3 노드 생성과 추가

DOM은 노드를 직접 생성/삽입/삭제/치환하는 메서드도 제공한다.

 

요소 노드 생성

Element.prototype.createElement(tagName) 메서드는 요소 노드를 생성하여 반환한다.

tagName에는 태그 이름을 나타내는 문자열을 인수로 전달한다.

 

텍스트 노드 생성

Element.prototype.createTextNode(text) 메서드는 텍스트 노드를 생성하여 반환한다.

text에는 텍스트 노드의 값으로 사용할 문자열을 인수로 전달한다.

 

텍스트 노드를 요소 노드의 자식 노드로 추가

Element.prototype.appendChild(childNode) 메서드는 매개변수 childNode에게 인수로 전달한 노드를 appendChild 메서드를 호출한 노드의 마지막 자식 노드로 추가한다.

 

39.6.4 복수의 노드 생성과 추가

<!DOCTYPE html>
<html>
    <body>
    	<ul id="fruits"></ul>
    </body>
    <script>
        const $fruits = document.getElementById('fruits');
        
        //DocumentFragment 노드 생성
        const $fragment = document.createDocumentFragment();
        
        ['Apple', 'Banana', 'Orange'].forEach(text => {
            //1. 요소 노드 생성
            const $li = document.createElement('li');
            
            //2. 텍스트 노드 생성
            const textNode = document.createTextNode(text);
            
            //3. 텍스트 노드를 $li 요소 노드의 자식 노드로 추가
            $li.appendChild(textNode);
            
            //4. $li 요소 노드를 DocumentFragment 노드의 마지막 자식 노드로 추가
            $fragment.appendChild($li);
        });
        
        //5. DocumentFragment 노드를 #fruits 요소 노드의 마지막 자식 노드로 추가
        $fruits.appendChild($fragment);
    </script>
</html>

 

 

39.6.5 노드 삽입

마지막 노드 추가

Node.prototype.appendChild 메서드는 인수로 전달받은 노드를 자신을 호출한 노드의 마지막 자식 노드로 DOM에 추가한다. 이때 노드를 추가할 위치를 지정할 수 없고 언제나 마지막 자식 노드로 추가한다.

 

지정한 위치에 노드 삽입

Node.prototype.insertBefore(newNode, childNode) 메서드는 첫 번째 인수로 전달받은 노드를 두 번째 인수로 전달받은 노드 앞에 삽입한다.

 

39.6.6 노드 이동

DOM에 이미 존재하는 노드를 appendChild 또는 insertBefore 메서드를 사용하여 DOM에 다시 추가하면 현재 위치에서 노드를 제거하고 새로운 위치에 노드를 추가한다. 즉, 노드가 이동한다.

 

39.6.7 노드 복사

Node.prototype.cloneNode([deep: true | false]) 메서드는 노드의 사본을 생성하여 반환한다. 매개변수 deep에 true를 인수로 전달하면 노드를 깊은 복사하여 모든 자손 노드가 포함된 사본을 생성하고, false를 인수로 전달하거나 생략하면 노드를 얕은 복사하여 노드 자신만의 사본을 생성한다.

 

39.6.8 노드 교체

Node.prototype.replaceChild(newChild, oldChild) 메서드는 자신을 호출한 노드의 자식 노드를 다른 노드로 교체한다. oldChild 매개변수에 인수로 전달한 노드는 replaceChild 메서드를 호출한 노드의 자식 노드이어야 한다.

 

39.6.9 노드 삭제

Node.prototype.removeChild(child) 메서드는 child 매개변수에 인수로 전달한 노드를 DOM에서 삭제한다. 인수로 전달한 노드는 removeChild 메서드를 호출한 노드의 자식 노드이어야 한다.

 

 

39.7 어트리뷰트

39.7.1 어트리뷰트 노드와 attributes 프로퍼티

HTML 문서의 구성 요소인 HTML 요소는 여러 개의 어트리뷰트(속성)를 가질 수 있다. HTML 어트리뷰트는 HTML 요소의 시작 태그에 어트리뷰트 이름="어트리뷰트 값" 형식으로 정의한다.

<input id="user" type="text" value="ungmo2">

 

39.7.2 HTML 어트리뷰트 조작

Element.prototype.getAttribute/setAttribute 메서드를 사용하면 attributes 프로퍼티를 통하지 않고 요소 노드에서 메서를 통해 직접 HTML 어트리뷰트 값을 취득하거나 변경할 수 있어서 편리하다.

<!DOCTYPE html>
<html>
    <body>
    	<input id="user" type="text" value="ungmo2">
        <script>
        const $input = document.getElementById('user');
        
        //value 어트리뷰트 값을 취득
        const inputValue = $input.getAttribute('value');
        console.log(inputValue); //ungmo2
        
        //value 어트리뷰트 값을 변경
        $input.setAttribute('value', 'foo');
        console.log($input,getAttribute('value')); //foo
        
        //$input.hasAttribute('value'); value 어트리뷰트의 존재 확인
        //$input.removeAttribute('value'); value 어트리뷰트 삭제
        </script>
    </body>
</html>

 

39.7.3 HTML 어트리뷰트 vs. DOM 프로퍼티

HTML 어트리뷰트의 역할은 HTML 요소의 초기 상태를 지정하는 것이다. 즉, HTML 어트리뷰트 값은 HTML 요소의 초기 상태를 의미하며 이는 변하지 않는다.

 

요소 노드는 2개의 상태, 즉 초기화 상태와 최신 상태를 관리해야 한다. 요소 노드의 초기 상태는 어트리뷰트 노드가 관리하며, 요소 노드의 최신 상태는 DOM 프로퍼티가 관리한다. 

 

39.7.4 data 어트리뷰트와 dataset 프로퍼티

data 어트리뷰터와 dataset 프로퍼티를 사용하면 HTML 요소에 정의한 사용자 정의 어트리뷰트와 자바스크립트 간에 데이터를 교환할 수 있다.data 어트리뷰트는 data-user-id, data-role과 같이 data- 접두사 다음에 임의의 이름을 붙여 사용한다.

<!DOCTYPE html>
<html>
    <body>
    	<ul class="users">
            <li id="1" data-user-id="7621" data-role="admin">Liee</li>
            <li id="2" data-user-id="9524" data-role="subscriber">Kim</li>
        </ul>
    </body>
</html>

 

 

 

 

출처 : 이웅모. 「모던 자바스크립트 Deep Dive」. 위키북스. 2023

728x90