JavaScript [day 29]

HiWoong·2023년 2월 16일
0

JsStudy

목록 보기
29/34

블로그 기본 양식

대부분의 내용은 모던 자바스크립트 Deep Dive에서 공부한 내용을 정리했습니다.


39장 : DOM

  • DOM이란, HTML 문서의 계층적 구조와 정보를 표현하며 이를 제어할 수 있는 API, 즉 프로퍼티와 메서드를 제공하는 트리 자료구조다.

본문의 내용이 길고 자세하기 때문에 간추려서 작성하겠습니다.
세부 내용이 궁금하시다면 책을 사서 보시는걸 추천드려요!

  • 노드
<div class = "greeting"> Hello </div>

<div : 시작 태그
class : 어트리뷰트 이름
"greeting" : 어트리뷰트 값
Hello : 콘텐츠
</div> : 종료 태그

이러한 요소, 어트리뷰트, 텍스트 등을 트리 구조로 구성한 것이 DOM 트리다.
간단하게 정리하자면,
문서 노드 : DOM 트리의 최상위에 존재하는 루트 노드로서 document 객체를 가리킨다.
요소 노드 : HTML 요소를 가리키는 객체다.
어트리뷰트 노드 : HTML 요소의 어트리뷰트를 가리키는 객체다.
텍스트 노드 : HTML 요소의 텍스트를 가리키는 객체다.

이러한 노드 객체들은 상속 구조를 갖는데, 기본적으로 Object-EventTarget-Node를 갖는다.
Object는 객체 특성을 상속하고, EventTarget은 이벤트를 발생시키는 객체, Node는 트리 자료구조의 노드 객체 등의 특성을 기본적으로 상속하고 추가적으로 요소에 따른 구조를 갖는다.

예를 들어, input 요소 노드 객체Object-EventTarget-Node-Element-HTMLElement-HTMLInputElement의 프로토타입 체인을 갖는다.

이러한 노드를 사용하기 위해 DOM은 DOM API를 제공하고, 이것을 통해 HTML의 구조나 내용 또는 스타일 등을 동적으로 조작할 수 있다.

취득하는 방법에는 여러가지가 있는데,

<html>
  <body>
    <ul>
      <li id="apple">Apple</li>
      <li id="banana">Banana</li>
      <li id="Orange">Orange</li>
      <li class="pear">Pear</li>
      <li class="lemon">Lemon</li>
      <li class="melon">Melon</li>
    </ul>
    <script>
      // 두 번째 li 요소가 파싱되어 반환된다.
      // 전달된 id값을 갖는 요소가 없는 경우 null 반환
      const $elem1 = document.getElementById('banana');
      
      // 태그 이름이 li인 요소 노드를 모두 탐색하여 반환
      // HTMLCollection 객체에 담겨 반환됨
      const $elem2 = document.getElementsByTagName('li');
	  
      // class 값이  'pear'인 요소 노드를 모두 탐색하여 HTMLCollection 객체에 담아 반환
      const $elem3 = document.getElementsByClassName('pear');
      
      // class 어트리뷰트 값이 'lemon'인 첫 번째 요소 노드를 탐색하여 반환
      const $elem4 = document.querySelector('.lemon');
      
      // 모든 요소 노드를 탐색하여 반환한다.
      const $elem5 = document.querySelectorAll('*');
	  
      // 특정 요소 노드를 취득할 수 있는 지 확인
      $elem3.matches('li.pear');
    </script>
  </body>
</html>

위에서 언급된 HTMLCollection과 NodeList는 DOM API가 여러 개의 결과값을 반환하기 위한 DOM 컬렉션 객체다.
차이점으로는,
HTMLCollection : 노드 객체의 상태 변화를 실시간으로 반영시킴, 그대로 값을 가져와서 반복문으로 치환할 시 제대로 반영되지 않는다.
NodeList : 실시간으로 노드 객체의 상태 변경을 반영하지 않는다. 하지만 childNodes 프로퍼티가 반환하는 NodeList는 HTMLCollection 객체와 같이 실시간으로 반영하기 때문에 주의가 필요하다.

그러므로 안전하게 사용하려면 HTMLCollection이나 NodeList 객체를 배열로 변환하여 사용하는 것을 권장한다.

  • 노드 탐색
    HTML 문서의 공백 문자는 공백 텍스트 노드를 생성한다.

자식 노드 탐색 : Node.prototype.childNodes, Element.prototype.children, Node.prototype.firstChild, Node.prototype.lastChild, Element.prototype.firstElementChild, Element.prototype.lastElementChild
자식 노드 존재 확인 : Node.prototype.hasChildNodes
부모 노드 탐색 : Node.prototype.parentNode
형제 노드 탐색 : Node.prototype.previousSibling, Node.prototype.nextSibling, Element.prototype.previousElementSibling, Element.prototype.nextElementSibling
노드 정보 취득 : Node.prototype.nodeType, Node.prototype.nodeName

지금까지 살펴본 프로퍼티는 모두 읽기 전용 접근자 프로퍼티다. setter까지 포함한 프로퍼티는
Node.prototype.nodeValue, Node.prototype.textContent 프로퍼티다.

  • DOM 조작
    innerHTML, insertAdjacentHTML 메서드는 HTML 마크업 문자열을 파싱하여 노드를 생성하고 DOM에 반영한다.
    요소 노드 생성 : Document.prototype.createElement(tagName)
    텍스트 노드 생성 : Document.prototype.createTextNode(text)
    자식 노드로 추가 : Document.prototype.appendChild(childNode)
<html>
  <body>
    <ul id='fruits'>
      <li id="apple">Apple</li>
    </ul>
    <script>
      const $fruits = document.getElementById('fruits);
      
      // 요소 노드 생성
      const $li = document.createElement('li');
      
      // 텍스트 노드 생성
      const textNode = document.createTextNode('Banana');
      
      // 텍스트 노드를 $li 요소 노드의 자식 노드로 추가
      $li.appendChild(textNode);
      
      // $li 요소 노드를 #fruits 요소 노드의 마지막 자식 노드로 추가
      $fruits.appendChild($li);
    </script>
  </body>
</html>
  • 노드 삽입
    지정한 위치에 노드 삽입 : Node.prototype.insertBefore(newNode, childNode)

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

  • 노드 복사
    Node.prototype.cloneNode([deep: true | false])
    deep : true 일 시, 깊은 복사
    deep : false 일 시, 얕은 복사

  • 노드 교체
    Node.prototype.replaceChild(newChild, oldChild)

  • 노드 삭제
    Node.prototype.removeChild(child)

  • 어트리뷰트
    모든 어트리뷰트 노드의 참조는 유사 배열 객체이자 이터러블인 NameNodeMap 객체에 담겨서 요소 노드의 attributes 프로퍼티에 저장된다.
    Element.prototype.attributes 프로퍼티로 취득할 수 있다.
    Element.prototype.gettAttribute/setAttribute 메서드를 사용해 attributes 프로퍼티를 통하지 않고 요소 노드에서 메서드를 통해 직접 HTML 어트리뷰트 값을 취득하거나 변경할 수 있어 편리하다.

  • HTML 어트리뷰트와 DOM 프로퍼티
    HTML 어트리뷰트의 역할은 HTML 요소의 초기 상태를 지정하는 것이다. 이는 변하지 않는다.
    사용자가 입력한 최신 상태는 DOM 프로퍼티가 관리한다.
    즉, 요소 노드는 2개의 상태(초기 상태 / 최신 상태)를 관리해야 한다.

  • data 어트리뷰트와 dataset 프로퍼티
    data 어트리뷰트는 케밥케이스를 사용한다.
    data 어트리뷰트의 값은 HTMLElement.dataset 프로퍼티로 취득할 수 있다.

profile
방갑습니다

0개의 댓글