JavaScript DOM Control

Let's Just Go·2022년 6월 18일
0

JavaScript

목록 보기
4/10

JavaScript

DOM Control

자식 노드 탐색

  • 찾은 요소의 자식 노드를 찾아주는 명령어
    • $찾은요소.childNodes;

      • 자식 노드를 찾아주는데 텍스트 노드도 포함되어 찾아줌
    • $찾은요소.children;

      • 텍스트 노드를 굳이 찾아줄 필요가 없기 때문에 텍스트 노드를 제외하고 찾을 수 있음
    • $찾은요소.firstChild;

      • 요소의 첫번째 자식 노드 탐색 (텍스트 노드 포함 O)
    • $찾은요소.firstElementChild;

      • 요소의 첫번째 자식 노드 탐색 (텍스트 노드 포함 X)
    • $찾은요소.lastElementChild;

      • 요소의 마지막 자식 노드 탐색 (텍스트 노드 포함 X)
    • $찾은요소.hasChildNodes();

      • 요소의 자식 노드가 있는지 여부 확인
      • 텍스트 노드가 있을 시 true를 반환하고 없으면 false를 반환
    • Code

      <!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="grape">GRAPE</li>
          </ul>
      
          <div id="test">
      
          </div>
      
          <script>
              // 노드 탐색 기점이 되는 ul요소 취득 
              const $fruits = document.getElementById('fruits');
      
              // 기준 노드의 모든 자식 노드를 탐색 (텍스트 노드 포함)
              const $childNodes = $fruits.childNodes;
              console.log($childNodes);
      
              // 기준 노드의 모든 자식 노드를 탐색 (텍스트 노드 제외)
              const $children = $fruits.children;
              console.log($children);
      
              // 기준 노드의 첫번째 자식 노드를 탐색 
              // firstChild는 텍스트 노드가 나올 가능성이 존재
              const $firstChild = $fruits.firstChild;
              console.log($firstChild);
              console.log('first-element-child : ' + $fruits.firstElementChild);
              console.log('last-element-child : ' + $fruits.lastElementChild);
      
              
              
              // 기준 노드에 자식 노드가 있는지 여부 확인 
              // 텍스트 노드가 있을 시 true가 나올 수 있음
              const $test = document.getElementById('test');
              console.log($test.hasChildNodes());
      
              // 텍스트 노드를 제외한 요소 노드의 여부 확인 
              // 자식 요소 노드를 취한 뒤 length 값을 논리로 바꾸어서 확인
              console.log(!!$test.children.length);
          </script>
      
      </body>
      
      </html>

부모 및 형제 노드 탐색

  • 부모 및 형제 노드 탐색
    • $찾은요소.parentNode;

      • 찾은 요소의 부모 노드를 탐색
    • $찾은요소.previouseElementSibling;

      • $찾은요소.previousSibling;
      • 찾은 요소의 이전 형제 노드 탐색
    • $찾은요소.nextElementSibling;

      • $찾은요소.nextSibling;
      • 찾은 요소의 다음 형제 노드 탐색
    • Code

      <!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 class="wrap">
              <ul id="fruits">
                  <li class="apple">APPLE</li>
                  <li class="banana">BANANA</li>
                  <li class="grape">GRAPE</li>
              </ul>
          </div>
      
          <table id="board">
              <tr>
                  <td>A</td>
                  <td>B</td>
              </tr>
              <tr>
                  <td>C</td>
                  <td>D</td>
              </tr>
          </table>
      
          <script>
              const $banana = document.querySelector('.banana');
      
              // 부모 노드 탐색 
              const $parent = $banana.parentNode;
              console.log($parent);
      
              const $div = $banana.parentNode.parentNode;
              // div는 banana요소의 부모의 부모이므로 
              console.log($div);
      
              
              // 이전 형제노드 탐색 
              const $prev = $banana.previousElementSibling;
              console.log($prev);
      				
      		// 다음 형제노드 탐색
              const $next = $banana.nextElementSibling;
              console.log($next);
      
              // next의 다음 형제노드가 없어서 null이 옴
              const $next2 = $next.nextElementSibling;
              console.log($next2);
      
              const $board = document.getElementById('board');
              console.log($board.children);
              // table 태그는 자식 태그로 tbody라는 태그를 자동으로 삽입하기 때문에 
              // 다른 요소를 가져오기 위해서는 더 밑으로 내려가야함
      
              const $tbody = $board.children;
              console.log($tbody[0].children);
              // 이제는 tr두개가 뜸
          </script>
      </body>
      
      </html>

TextContent

  • textContent
    • $찾은요소.textContent;

      • 찾은 요소안에 있는 모든 텍스트를 가져옴 (마크업 제외)
    • Code

      <!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="greeting">
              Hello
              <span>World</span>
          </div>
      
          <script>
              const $div = document.getElementById('greeting');
              // console.log($div.childNodes[0].nodeValue);
              console.log($div.textContent)
              // div 태그안에 있는 모든 텍스트만 가져와라 (마크업 제외)
      
              $div.textContent = '<span>안녕</span>하세요';
              // 태그를 작성해도 텍스트로 인식
          </script>
      
      </body>
      
      </html>

Innser HTML

  • inner HTML
    • 문자열 형태로 tag와 text를 작성하게 되면 실제 페이지에 노드를 추가할 수 있음

    • $찾은요소.innerHTML;

      • 태그까지 모두 가져올 수 있음
    • $찾은요소.innerHTML += ‘추가할 것’;

      • 찾은 요소에 노드를 추가하는 방법
      • 추가할 것에 태그를 포함하여 입력하면 추가가 됨
    • innerHTML로 노드를 제어하면 보안과 성능에 문제가 있음

    • Code

      <!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>
          </ul>
      
          <script>
              const $fruits = document.getElementById('fruits');
              console.log($fruits.innerHTML);
              // 태그가 모두 포함됨
      
              // 노드 추가 
              $fruits.innerHTML += '<li class="banana">BANANA</li>';
              
              // li의 apple 뒤에 노드 추가
      
              $fruits.innerHTML = '';
      
              console.log(!!$fruits.children.length);
      
              /*
                  innerHTML로만 노드를 제어하면 안됨 
                  왜냐면 보안과 성능에 문제가 있음 
                  그래서 HTML 변환이 필요한 문자열에만 사용하는게 좋음
              */
          </script>
      </body>
      
      </html>

노드 생성 및 추가

  • 노드 생성 및 추가
    • document.createElement(’tag name’);

      • 요소 노드 생성
    • 생성노드.textContet = ‘텍스트';

      • 생성한 요소에 text 추가
    • 부모노드.appendChild(생성노드);

      • 생성한 노드를 맨 마지막에 추가
    • Code

      <!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>Apple</li>
          </ul>
      
          <script>
              const $fruits = document.getElementById('fruits');
      
              // 요소 노드 생성 
              const $newLi = document.createElement('li');
      
              // 텍스트 삽입 
              $newLi.textContent = 'Banana';
      
              // ul에 추가
              $fruits.appendChild($newLi);
          </script>
      
      </body>
      
      </html>

복수 노드 생성 및 추가

  • 복수 노드 생성 및 추가
    • live DOM에 가상의 DOM을 반복적으로 넣는 행위는 메모리 cost를 높이기 때문에 가상의 DOM을 생성해서 한번만 live DOM에 넣으면 메모리 cost 절약 가능

    • document.createDocumentFragment();

      • 가상의 DOM 생성
    • Code

      <!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>
      
          <script>
              // live DOM : 사전에 미리 렌더링 되어 있는 요소 노드 (실제로 만들어져있는 노드)
              const $fruits = document.getElementById('fruits');
      
              const fruitName = ['Apple', 'Banana', 'Grape', 'Orange'];
      
              /*
              이미 활성화된 live DOM에 반복해서 가상 DOM을 추가하는 것은 메모리상에서 높은 코스트가 발생
              활성화된 DOM을 변경 조작하는 것은 가능한 한 횟수를 줄여야함
              */
      
              // li에 배열의 값을 반복으로 넣어줌
              // for (let f of fruitName){
              //     const $li = document.createElement('li');
              //     $li.textContent = f;
              //     $fruits.appendChild($li);
              // }
      
              // 가상의 부모 DOM생성 다른 노드를 담는 임시 컨테이너 역할을 하는 가상 DOM 객체 
              const $frag = document.createDocumentFragment();
              for (let f of fruitName) {
                  const $li = document.createElement('li');
                  $li.textContent = f;
                  $frag.appendChild($li);
                // 가상 DOM인 frag에 li에 넣어주고
              }
              $fruits.appendChild($frag);
              // 마지막으로 진짜 DOM에 가상 DOM을 한번만 넣어줌
              
          </script>
      </body>
      
      </html>

노드 삽입

  • 노드 삽입
    • appendChild()와 다르게 삽입 위치 설정 가능

    • $찾은요소.insertBefore(삽입하고 싶은 요소, 이동의 기준이 될 요소);

      • 이동의 기준이 될 요소 앞에 삽입하고 싶은 요소가 들어감
      • 찾은 요소의 자식이어야 삽입 가능
    • Code

      <!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>Apple</li>
              <li>Banana</li>
              <li>Grape</li>
          </ul>
      
          <script>
              const $fruits = document.getElementById('fruits');
      
              const $li = document.createElement('li');
              $li.textContent = 'Mango';
      
              // 두번째 매개값으로 전달된 노드는 반드시 insertBefore를 호출한 노드의 자식이여야함
              $fruits.insertBefore($li, $fruits.lastElementChild);
      
              // 이미 배치된 DOM을 다시 한번 insertBefore하면 노드가 이동
              const $banana = document.querySelector('#fruits > li:nth-child(2)');
              $fruits.insertBefore($banana, $fruits.firstElementChild);
          </script>
      </body>
      
      </html>

노드 복사

  • 노드 복사
    • $찾은요소.cloneNode();

      • 얕은 복사 (자기 자신 노드 태그만 복사)
    • $찾은요소.cloneNode(true);

      • 깊은 복사 (자기 자신을 포함한 모든 자손 노드 복사)
      • 깊은 복사는 매개 값으로 true를 작성하면 됨
    • Code

      <!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>Apple</li>
          </ul>
          <script>
              const $fruits = document.getElementById('fruits');
              const $apple = $fruits.firstElementChild;
      
              // apple의 사본 생성 (얕은 복사 : 자기 자신 노드만 복사)
              const $shallowClone = $apple.cloneNode();
              console.log($shallowClone);
              $shallowClone.textContent = $apple.textContent;
              // apple의 text를 shallowclone에 넣어줌
              $fruits.appendChild($shallowClone);
              // fruit에 값을 넣어줌
      
              // apple의 사본 생성 (깊은 복사 : 자기 자신을 포함한 모든 자손 노드를 복사)
              const $deepClone = $apple.cloneNode(true);
              $fruits.appendChild($deepClone);
      
              // ul을 깊은 복사 
              const $ulClone = $fruits.cloneNode(true);
              $fruits.appendChild($ulClone);
          </script>
      
      </body>
      
      </html>

노드 교체 및 삭제

  • 노드 교체 및 삭제
    • $찾은요소. replaceChild(교체할 값, 교체 대상);

      • 교체할 값으로 교체 대상을 교체
    • $찾은요소.removeChild(삭제할 값);

      • 요소를 삭제
    • Code

      <!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>Apple</li>
              <li>Banana</li>
          </ul>
      
          <script>
              const $fruits = document.getElementById('fruits');
      
              // 요소 추가
              const $mango = document.createElement('li');
              // 요소를 먼저 만듬
              $mango.textContent = 'Mango';
              // 내부 값 입력
      
              $fruits.replaceChild($mango, $fruits.firstElementChild);
              // fruits의 첫번째 자식을 mango로 교체
      
              $fruits.removeChild($fruits.lastElementChild);
              // fruits의 마지막 자식을 삭제
          </script>
      </body>
      
      </html>
profile
안녕하세요! 공부한 내용을 기록하는 공간입니다.

0개의 댓글