ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • DOM - 노드
    JavaScript/DOM 2022. 11. 26. 12:16

    노드 탐색

    - 요소노드를 취득한 다음, 취득한 요소 노드를 기점으로 DOM트리의 노드를 옮겨 다니며 부모, 형제, 자식, 노드 등을 탐색해야 할 때가 있다 

     

    - parentNode, previousSibling, nextSibling, firstChild,lastChild, childNodes 프로퍼티는 Node.prototype 이 제공하고,

    프로퍼티 키에 Element가 포함된 previousElementSibling, nextElemenbSibling, firstElementChild, lastElementChild, children 프로퍼티는 Element.prototype이 제공한다 

    - Node.prototype는 setter없는 읽기 전용 접근자 프로퍼티 

     

    공백 테스트 노드

    - HTML요소 사이의 스테이스, 탭, 줄바꿈 등의 공백 문자는 텍스트 노드를 생성 => 공백 텍스트 노드 

    https://go.gliffy.com/go/html5/launch

     

    # 그림 넣기 page 702 

     

     

    자식 노드 탐색 

       프로퍼티 설명
    Node.prototype.childNodes 자식 노드를 모두 탐색하여 DOM 컬렉션 객체인 NodeList에 담아 반환. childNodes 프로퍼티가 반환한 NodeList에는 요소 노드뿐만 아니라 텍스트 노드도 포함되어 있을 수 있다 
    Element.prototype.children 자식 노드 중에서 요소 노드만 모두 탐색하여 DOM컬렉션 객체인 HTMLCollection에 담아 반환한다. children 프로퍼티가 반환한 HTMLCollection에는 텍스트 노드가 포함되지 않는다
    Node.prototype.firstchild 첫 번째 자식 노드를 반환. firstchild프로퍼티가 반환한 노드는 텍스트 노드이거나 요소 노드 
    Node.prototype.lastchild 마지막 자식 노드를 반환. lastchild프로퍼티가 반환한 노드는 
    텍스트 노드이거나 요소 노드
    Element.prototype.firstElementChild 첫 번째 자식 요소 노드를 반환. firstElementChild 프로퍼티는 
    요소 노드만 반환 
    Element.prototype.lastElementChild 마지막 자식 요소 노드를 반환. lastElementChild 프로퍼티는 
    요소 노드만 반환

     

    <!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>
        <ul id="fruits">
          <li class="apple">Apple</li>
          <li class="banana">Banana</li>
          <li class="orange">Orange</li>
        </ul>
    </body>
        <script>
            // 노드 탐색의 기점이 되는 fruits 획득 
            const fruits = document.getElementById('fruits'); 
    
            // ChildrenNodes는 Nodelist를 반환 
            // 요소 노드뿐만 아니라 텍스트 노드도 있다 
            console.log(fruits.childNodes); // // NodeList(7) [text, li.apple, text, li.banana, text, li.orange, text]
            
            // Children는 HTMLCollections를 반환 
            // 요소 노드만 포함되어 있다 
            console.log(fruits.children); // HTMLCollection(3) [li.apple, li.banana, li.orange]
    
            // firstChild프로퍼티는 텍스트 노드를 반환할 수 있다 
            console.log(fruits.firstChild); //text
            
            // lastChild프로퍼티는 텍스트 노드를 반환할 수 있다 
            console.log(fruits.lastChild); //text
    
            // firstElementChild 프로퍼티는 요소 노드만 반환 
            console.log(fruits.firstElementChild); // li.apple
    
            // lastElemetChild 프로퍼티는 요소 노드만 반환 
            console.log(fruits.lastElementChild); // li.orange
        </script>
    </html>

     

     

    자식 노드 존재 확인

    Node.prototype.hasChildNodes 

    - 자식 노드가 존재하면 true, 존재하지 않은면 false를 반환 

    - 텍스트 노드를 포함한 자식 노드의 존재를 확인 

     

    자식 노드 중에 텍스트 노드가 아닌 요소 노드가 존재하는지 확인하려면?! 

    -  children.length 또는 Element 인터페이스의 childElementCount 프러퍼티사용

     

    <!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>
        <ul id="fruits">     
        </ul>
    </body>
        <script>
            // 노드 탐색의 기점이 되는 #fruits 요소 노드를 취득 
            const fruits = document.getElementById('fruits');          
            console.log(fruits.hasChildNodes()); // true 
    
            // 자식 노드 중에 텍스트 노드가 아닌 요소 노드가 존재하는지 확인 
            console.log(fruits.children.length); // 0 
            console.log(fruits.childElementCount); // 0      
        
        </script>
    </html>

     

    요소 노드의 텍스트 노드 탐색 

    - 요소 노드의 텍스트 노드는 firstChild 프로퍼티로 접근할 수 있다. firstChild는 첫 번째 자식 노드를 반환한다 

    - firstChild프로퍼티가 반환한 노드는 텍스트 노드이거나 요소 노드이다 

    <!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="foo">Hello</div>
    </body>
        <script>
            // 요소 노드의 텍스트 노드는 firstChild 프로퍼티로 접근할 수 있다 
            console.log(document.getElementById('foo').firstChild);  // #text          
        </script>
    </html>

     

    부모 노드 탐색 

    - Node.prototype.parentNode 프러퍼티 사용 

    <!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>
       <ul id="fruits">
        <li class="apple">Apple</li>
        <li class="banana">Banana</li>
        <li class="orange">Orange</li>
       </ul>
    </body>
        <script>
            const banana = document.querySelector('.banana'); 
            console.log(banana.parentNode); // ul#fruits
        </script>
    </html>

     

    형제 노드 탐색 

    프로퍼티  설명 
    Node.prototype.previousSibling  부모 노드가 같은 형제 노드 중에서 이전 형제 노드를 탐색하여 반환. 요소 노드 뿐만 아니라, 텍스트 노드가 반환될 수 있음
    Node.prototype.nextSibling  부모 노드가 같은 형제 노드 중에서 다음 형제 노드를 탐색하여 반환. 요소 노드 뿐만 아니라, 텍스트 노드가 반환될 수 있음
    Element.prototype.previosElementSibling 부모 노드가 같은 형제 노드 중에서 이전 형제 노드를 탐색하여 반환. 요소 노드만 반환 
    Element.prototype.nextElementSibling 부모 노드가 같은 형제 노드 중에서 다음 형제 노드를 탐색하여 반환. 요소 노드만 반환

     

    <!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>
        <ul id="fruits">
            <li class="apple">Apple</li>
            <li class="banana">Banana</li>
            <li class="orange">Orange</li>
        </ul>
    </body>
    <script>
        const fruits = document.getElementById('fruits'); 
    
        // firstChild 프로퍼티는 요소노드 or 텍스트 노드를 반환 
        const { firstChild } = fruits; 
        console.log(firstChild); // #text
    
        // nextSibling 프로퍼티는 요소노드 or 텍스트 노드를 반환 
        const { nextSibling } = firstChild; 
        console.log(nextSibling); // li.apple 
    
        // prveiousibling 프로퍼티는 요소노드 or 텍스트 노드를 반환 
        const { previousSibling } = nextSibling; 
        console.log(previousSibling); // #text 
    
    
        // firstElementChild 프러퍼티는 요소노드만 반환 
        const { firstElementChild } = fruits;
        console.log(firstElementChild); // li.apple 
    
        // nextElementChild 프러퍼티는 요소노드만 반환 
        const { nextElementSibling } = firstElementChild; 
        console.log(nextElementSibling); // li.banana 
    
        
    </script>
    </html>

    노드 정보 취득 

    프로퍼티  설명 
    Node.prototype.nodeType 노드 객체의 종류, 노드 타입을 나타나는 상수를 반환 
    - Node.ELEMENT_NODE: 요소 노드 타입 반환, 1 
    - Node.TEXT_NODE: 텍스트 노드 타입 반환, 3
    - Node.DOCUMENT_NODE: 문서 노드 타입을 반환, 9 
    Node.prototype.nodeName 노드의 이름을 문자열로 반환 
    - 요소 노드: 대문자 문자열로 태그이름(ul, li) 을 반환 
    - 텍스트 노드: 문자열 '#text'를 반환 
    - 문서 노드: 문자열 '#documenet' 를 반환 
    <!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="foo">Hello</div>
    </body>
    <script>
        console.log(document.nodeType); // 9 
        console.log(document.nodeName); // document 
        
        const foo = document.getElementById('foo'); 
        console.log(foo.nodeType);  // 1 
        console.log(foo.nodeName); // div 
    
        const textNode = foo.firstChild; 
        console.log(textNode.nodeType);  // 3
        console.log(textNode.nodeName); //#text
    </script>
    </html>

    요소 노드의 텍스트 조작

    Node.prototype.nodeValue 

    - setter, getter 모두 존재하는 프로퍼티. 따라서 nodeValue는 프러퍼티는  참조와 할당이 모두 가능 

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

    - 텍스트 노드가 아닌, 문서노드나 요소 노드의 nonvalue 프러퍼티를 참조하면은 null를 반환 

     

    <!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="foo">Hello</div>
    </body>
    <script>
        // document 노드 
        console.log(document.nodeValue); // null 
        
        // 요소 노드 
        const foo = document.getElementById('foo'); 
        console.log(foo.nodeValue); // null 
    
        // 텍스트 노드 
        const textNode  = foo.firstChild;
        console.log(textNode.nodeValue);  // Hello  
    
    </script>
    </html>

    텍스트 노드로만 텍스트에 접근이 가능하기 떄문에 요소노드나 document 노드에 nodeValue를 할당해도 아무 의미 X 

    따라서 요소노드에 텍스트를 바꾸려면?!

    1. 텍스트를 변경할 요소 노드를 취득한 다음에, 취득한 요소 노드의 텍스트 노드를 탐색. 
    텍스트 노드는 요소 노드의 첫번째 자식 노드이므로 firstChild 프로퍼티를 사용하여 탐색한다 
    
    2. 텍스트 노드의 nodeValue프러퍼티를 사용하여 텍스트 노드의 값을 변경
    <!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="foo">Hello</div>
    </body>
    <script>
        // 해당 요소를 탐색 
        const textNode = document.getElementById('foo').firstChild;
        textNode.nodeValue = 'World';     
        console.log(textNode.nodeValue); // World  
    </script>
    </html>

    Node.prototype.textContent 

    - setter와 getter 모두 존재하는 접근자 프로퍼티. 값을 취득, 할당 모두 가능

    - 요소노드와 모든 자손 노드의 텍스트를 취득하거나 변경할 수 있다 

    - 요소 노드의 textContent 프로퍼티를 참조하면은 요소 노드의 콘텐츠 영역(시작 태그와 종료 태그 사이) 내의 텍스트를 반환한다 (HTMl 마크업 무시) 

     

     

    textContent 프로퍼티에 의한 텍스트 취득

    <!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="foo">Hello<span>World!</span></div>
    </body>
    <script>
        // textContent를 이용하여 text를 반환 
        console.log(document.getElementById('foo').textContent); // HelloWorld! 
    
    </script>
    </html>

     

    nodeValue 프로퍼티에 의한 텍스트 취득

    <!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="foo">Hello<span>World!</span></div>
    </body>
    <script>
          // nodevalue를 이용하여 text를 반환, nodevalue는 textnode에서만 사용할 수 있음. 따라서 textNode를 구하는게 우선   
          const textNode = document.getElementById('foo').childNodes; // NodeList(2) [text, span]
          console.log(textNode[0]); // #text
          console.log(textNode[0].nodeValue); // Hello 
      
          console.log(textNode[1]); // span 
          console.log(textNode[1].firstChild); // #text
          console.log(textNode[1].firstChild.nodeValue); // world!   
    </script>
    </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="foo">Hello<span>World!</span></div>
    </body>
    <script>
    	
    </script>
    </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="foo">Hello<span>World!</span></div>
    </body>
    <script>
        console.log(document.getElementById('foo').firstChild.nodeValue); // hello
        console.log(document.getElementById('foo').lastChild.firstChild.nodeValue);  // wordl
    </script>
    </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="foo">Hello</div>
    </body>
    <script>
        // 요노소드의 컨텐츠 영역에 자식 요소 노드가 없고, 텍스트만 존재한다면?! 
        // textContent와 firstChild.nodevalue는 같은 결과 반환 
        const foo = document.getElementById('foo'); 
        console.log(foo.textContent === foo.firstChild.nodeValue); // true 
    </script>
    </html>

    요소노드의 textContent 프로퍼티에 문자열을 할당하면 요소 노드의 모든 자식 노드가 제거가 되고 할당한 문자열이 텍스트로 문자된다

    <!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="foo">Hello <span>world!</span></div>
    </body>
    <script>
        document.getElementById('foo').textContent = 'Hi <span> there! </span>';
    </script>
    </html>

     

    cf. textContent 프러퍼티와 유사한 동작을 하는 innerText 프로퍼티가 있다. innerText 프로퍼티는 다음과 같은 이유로 사용하지 않는 것이 좋다. 

    - innerText 프로퍼티는 CSS에 순종적. 예를 들어, innerText 프로퍼티는 CSS에 의해 비표시(visibility: hiddden;) 로 지정된 요소 노드의 텍스트를 반환하지 않는다 

     

    - innerText 프로퍼티는 CSS를 고려해야 하므로 textContent프로퍼티보다 느리다 

    'JavaScript > DOM' 카테고리의 다른 글

    <script>태그 위치  (0) 2023.01.11
    DOM조작  (0) 2022.11.26
    DOM요소에 접근하고 속성 가져오기  (0) 2022.11.23
    스타일(css style)다루기  (0) 2022.11.22
    속성(Attribute)와 프러퍼티(Property)  (0) 2022.11.21

    댓글

Designed by Tistory.