쑤쑤_CS 기록장

31. 문서 객체 모델(Document Object Model) 본문

IT 지식 기록/JavaScript 정리

31. 문서 객체 모델(Document Object Model)

(╹◡╹)_ 2020. 12. 25. 11:32
728x90

#1. DOM ( Document Object Model )

DOM

  • 브라우저의 렌더링 엔진
    : 웹 문서를 로드 -> 파싱하여 웹 문서를 브라우저가 이해할 수 있는 구조로 구성 ->메모리에 적재 
  • 모든 요소와 어트리뷰트, 텍스트를 각각의 객체로 만들고 이를 부자 관계로 표현할 수 있는 트리구조로 구성한 것

 

DOM API (Application Programming Interface)

  • 웹 문서의 동적 변경을 위해  일반적으로 프로퍼티와 메소드를 갖는 자바스크립트 객체로 제공
  • 정적인 웹페이지에 접근하여 동적으로 웹페이지를 변경하기 위한 방법 : DOM 변경

  • DOM에 접근하고 변경하는 프로퍼티와 메소드의 집합 : DOM API

< DOM의 기능(2) >

- HTML 문서에 대한 모델 구성

: 브라우저는 HTML 문서를 로드한 후 해당 문서에 대한 모델을 메모리에 생성한다. 이때 모델은 객체의 트리로 구성되는데 이것을 DOM tree라 한다.

- HTML 문서 내의 각 요소에 접근 / 수정

: DOM은 모델 내의 각 객체에 접근하고 수정할 수 있는 프로퍼티와 메소드를 제공한다. DOM이 수정되면 브라우저를 통해 사용자가 보게 될 내용 또한 변경된다.

 

#2. DOM tree

: 브라우저가 HTML 문서를 로드한 후 파싱하여 생성하는 모델. 객체의 트리로 구조화되어있다.

<!DOCTYPE html>
<html>
  <head>
    <style>
      .red  { color: #ff0000; }
      .blue { color: #0000ff; }
    </style>
  </head>
  <body>
    <div>
      <h1>Cities</h1>
      <ul>
        <li id="one" class="red">Seoul</li>
        <li id="two" class="red">London</li>
        <li id="three" class="red">Newyork</li>
        <li id="four">Tokyo</li>
      </ul>
    </div>
  </body>
</html>

  • 모든 요소, 어트리뷰트, 텍스트는 하나의 객체. Document 객체의 자식

  • 진입점(Entry point)은 document 객체

  • 최종점은 요소의 텍스트를 나타내는 객체

< DOM tree의 노드(4) >

  • 문서 노드(Document Node)
    : 트리의 최상위에 존재하며 각각 요소, 어트리뷰트, 텍스트 노드에 접근하려면 문서 노드를 통해야 한다. 즉, DOM tree에 접근하기 위한 시작점(entry point)이다.
  • 요소 노드(Element Node)
    : 요소 노드는 HTML 요소를 표현한다. HTML 요소는 중첩에 의해 부자 관계를 가지며 이 부자 관계를 통해 정보를 구조화한다. 따라서 요소 노드는 문서의 구조를 서술한다고 말 할 수 있다. 어트리뷰트, 텍스트 노드에 접근하려면 먼저 요소 노드를 찾아 접근해야 한다. 모든 요소 노드는 요소별 특성을 표현하기 위해 HTMLElement 객체를 상속한 객체로 구성된다.
  • 어트리뷰트 노드(Attribute Node)
    : 어트리뷰트 노드는 HTML 요소의 어트리뷰트를 표현한다. 어트리뷰트 노드는 해당 어트리뷰트가 지정된 요소의 자식이 아니라 해당 요소의 일부로 표현된다. 따라서 해당 요소 노드를 찾아 접근하면 어트리뷰트를 참조, 수정할 수 있다.
  • 텍스트 노드(Text Node)
    : 텍스트 노드는 HTML 요소의 텍스트를 표현한다. 텍스트 노드는 요소 노드의 자식이며 자신의 자식 노드를 가질 수 없다. 즉, 텍스트 노드는 DOM tree의 최종단이다.

DOM tree의 객체 구성

 

#3. DOM Query / Traversing (요소에의 접근)

3.1 하나의 요소 노드 선택 (DOM Query)

  • document.getElementById(id)
    • id 어트리뷰트 값으로 요소 노드를 한 개 선택

    • 복수개가 선택될 경우, 첫번째 요소만 반환

    • Return : HTMLElement를 상속받은 객체

  • document.querySelector(cssSelector)
    • CSS 셀렉터를 사용하여 요소 노드를 한 개 선택

    • 복수개가 선택될 경우, 첫번째 요소만 반환

    • Return : HTMLElement를 상속받은 객체

#3.2 여러 개의 요소 노드 선택 (DOM Query)

  • document.getElementsByClassName(class)

    • class 어트리뷰트 값으로 요소 노드를 모두 선택
    • 공백으로 구분하여 여러 개의 class 지정 가능
    • Return : HTMLCollection(live)
  • document.getElementsByTagName(tagName)

    • 태그명으로 요소 노드를 모두 선택
    • Return : HTMLCollection(live)
  • document.querySelectorAll(selector)

    • 지정된 CSS 선택자를 사용하여 요소 노드를 모두 선택
    • Return : NodeList (non-live)

#3.3 DOM Traversing (탐색)

  • parentNode
    • 부모 노드를 탐색
    • Return : HTMLElement를 상속받은 객체
  • firstChild, lastChild
    • 자식 노드를 탐색
    • Return : HTMLElement를 상속받은 객체
  • hasChildNodes()
    • 자식 노드가 있는지 확인하고 Boolean 값을 반환
    • Return : Boolean 값
  • childNodes
    • 자식 노드의 컬렉션을 반환
    • 텍스트 요소를 포함한 모든 자식 요소를 반환
    • Return : NodeList (non-live)
  • children
    • 자식 노드의 컬렉션을 반환
    • 자식 요소 중에서 Element type 요소만을 반환
    • Return : HTMLCollection(live)
  • previousSibling, nextSibling
    • 형제 노드를 탐색
    • text node를 포함한 모든 형제 노드를 탐색
    • Return : HTMLElement를 상속받은 객체
  • previousElementSibling, nextElementSibling
    • 형제 노드를 탐색
    • 형제 노드 중에서 Element type 요소만을 탐색
    • Return : HTMLElement를 상속받은 객체

 

4. DOM Manipulation (조작)

#4.1 텍스트 노드의 접근/수정

요소의 텍스트는 텍스트 노드에 저장되어 있다.

< 텍스트 노드에 접근하기위한 순서 >

  1. 해당 텍스트 노드의 부모 노드를 선택한다. 텍스트 노드는 요소 노드의 자식이다.
  2. firstChild 프로퍼티를 사용하여 텍스트 노드를 탐색한다.
  3. 텍스트 노드의 유일한 프로퍼티(nodeValue)를 이용하여 텍스트를 취득한다.
  4. nodeValue를 이용하여 텍스트를 수정한다.

 

  • nodeValue
    • 노드의 값을 반환
    • Return : 텍스트 노드 → 문자열 / 요소 노드 → null
  • nodeName
  • nodeType

#4.2 어트리뷰트 노드의 접근/수정

  • className

    • class 어트리뷰트의 값을 취득 또는 변경

    • 프로퍼티에 값을 할당하는 경우, class 어트리뷰트가 존재하지 않으면 생성 후 지정된 값을 설정

    • 값이 여러 개일 경우, 공백으로 구분된 문자열이 반환

  • classList

    • add / remove / item / toggle / contains / replace 메소드 제공
  • id

    • id 어트리뷰트의 값을 취득 또는 변경

    • 프로퍼티에 값을 할당하는 경우, 존재하지 않는 경우 생성 후 지정된 값을 설정

  • hasAttribute(attribute)

    • 지정한 어트리뷰트를 가지고 있는지 검사
    • Return : Boolean
  • getAttribute(attribute)

    • 어트리뷰트의 값을 취득
    • Return : 문자열
  • setAttribute(attribute, value)

    • 어트리뷰트와 어트리뷰트 값을 설정
    • Return : undefined
  • removeAttribute(attribute)

    • 지정한 어트리뷰트를 제거
    • Return : undefined

#4.3 HTML 콘텐츠 조작(Manipulation)

  • textContent
    • 요소의 텍스트 콘텐츠 취득 또는 변경
    • 마크업은 무시된다
  • innerText
    • 텍스트 콘텐츠에만 접근 가능
    • 하지만 사용하지 않는 것을 권유
  • innerHTML
    • 해당 요소의 모든 자식 요소를 포함하는 모든 콘텐츠를 하나의 문자열로 취득
    • 마크업을 포함

#4.4 DOM 조작 방식

innerHTML 프로퍼티를 사용하지 않고 새로운 콘텐츠를 추가할 수 있는 방법 : DOM을 직접 조작

한 개의 요소를 추가하는 경우 사용한다. 

< 순서 >

  1. 요소 노드 생성 createElement() 메소드를 사용하여 새로운 요소 노드를 생성한다.
    createElement() 메소드의 인자로 태그 이름을 전달한다.

  2. 텍스트 노드 생성 createTextNode() 메소드를 사용하여 새로운 텍스트 노드를 생성한다.
    경우에 따라 생략될 수 있지만 생략하는 경우, 콘텐츠가 비어 있는 요소가 된다.

  3. 생성된 요소를 DOM에 추가 appendChild() 메소드를 사용하여 생성된 노드를 DOM tree에 추가한다.
    또는 removeChild() 메소드를 사용하여 DOM tree에서 노드를 삭제할 수도 있다.

 

  • createElement(tagName)
    • 태그이름을 인자로 전달하여 요소를 생성
    • Return : HTMLElement 를 상속받은 객체
  • createTextNode(text)
    • 텍스트를 인자로 전달하여 텍스트 노드를 생성
    • Return : Text 객체
  • appendChild(Node)
    • 인자로 전달한 노드를 마지막 자식 요소로 DOM 트리에 추가
    • Return : 추가한 노드
  • removeChild(Node)
    • 인자로 전달한 노드를 DOM 트리에서 제거
    • Return : 추가한 노드

#4.5 insertAdjacentHTML()

  • insertAdjacentHTML(position, string)
    • 인자로 전달한 텍스트를 HTML로 파싱

    • 결과로 생성된 노드를 DOM 트리의 지정된 위치에 삽입

#4.6 innerHTML vs DOM 조작 방식 vs insertAdjacentHTML()

 

  • innerHTML과 insertAdjacentHTML()은 크로스 스크립팅 공격에 취약
  • untrusted data의 경우, 주의
  • 텍스트를 추가 또는 변경시에는 textContent 사용
  • 새로운 요소의 추가 또는 삭제시에는 DOM 조작 방식 사용

#5. style

  • style 프로퍼티를 사용하면 inline 스타일 선언을 생성한다.
  • style 프로퍼티의 값을 취득하려면 window.getComputedStyle을 사용한다.

const four = document.getElementById('four');

// inline 스타일 선언을 생성
four.style.color = 'blue';

// font-size와 같이 '-'으로 구분되는 프로퍼티는 카멜케이스로 변환하여 사용한다.
four.style.fontSize = '2em';

 

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>style 프로퍼티 값 취득</title>
  <style>
    .box {
      width: 100px;
      height: 50px;
      background-color: red;
      border: 1px solid black;
    }
  </style>
</head>
<body>
  <div class="box"></div>
  <script>
    const box = document.querySelector('.box');

    const width = getStyle(box, 'width');
    const height = getStyle(box, 'height');
    const backgroundColor = getStyle(box, 'background-color');
    const border = getStyle(box, 'border');

    console.log('width: ' + width);
    console.log('height: ' + height);
    console.log('backgroundColor: ' + backgroundColor);
    console.log('border: ' + border);

    /**
     * 요소에 적용된 CSS 프로퍼티를 반환한다.
     * @param {HTTPElement} elem - 대상 요소 노드.
     * @param {string} prop - 대상 CSS 프로퍼티.
     * @returns {string} CSS 프로퍼티의 값.
     */
    function getStyle(elem, prop) {
      return window.getComputedStyle(elem, null).getPropertyValue(prop);
    }
  </script>
</body>
</html>
728x90

'IT 지식 기록 > JavaScript 정리' 카테고리의 다른 글

33. 이벤트  (1) 2020.12.28
32. 동기식 처리 모델 vs 비동기식 처리 모델  (0) 2020.12.28
30. 배열 고차 함수  (0) 2020.12.25
29. 자바스크립트 배열은 배열이 아니다  (0) 2020.12.25
28. 배열  (0) 2020.12.25
Comments