[JavaScript] 문서 객체 모델(DOM)

2023. 2. 8. 05:34JavaScript

1. 문서 객체 모델(DOM)

- DOM : Document Object Model

- 웹 문서의 모든 요소를 자바스크립트를 이용해 조작할 수 있도록 객체를 사용하여 문서를 해석하는 방법

- 웹 문서의 모든 요소들을 객체로 만들고 이를 트리 구조로 구성한 모델

 

- DOM 트리 구조 : 웹 문서의 요소를 부모와 자식 요소로 구성된 트리 구조

2. 여러 DOM 노드

https://en.wikipedia.org/wiki/Document_Object_Model

  • 문서 노드(Document Node)
    - 트리의 최상위 존재하며, 하위 자식 노드에 접근하기 위해선 반드시 Document Node를 통해야만 한다.
    - DOM 트리에 접근하기 위한 시작점
  • 요소 노드(Element Node)
    - 웹 문서의 태그 Element Node로 표현
    - 모든 Element Node는 Attribute/Text Node를 자식으로 가질 수 있는데, 이 자식 노드들을 변경하여 웹 페이지를 동적으로 조작할 수 있다.
  • 속성 노드(Attribute Node)
    - 태그의 모든 속성은 Attribute Node로 표현하며 해당 태그의 자식 노드로 인식
  • 텍스트 노드(Text Node)
    - 태그가 가지고 있는 택스트는 해당 Element Node의 자식 노드인 Text Node로 표현된다.
    - Text Node는 Dom 트리의 가장 아래쪽에 위치하여 자신의 자식 노드는 가질 수 없다.
  • 주석 노드(Comment Node)
    - 주석은 Comment Node로 표현

3. DOM 렌더링

https://web.dev/howbrowserswork/

- 일반적으로 DOM을 이용해 화면을 표시하는 렌더링은

HTML 파싱 -> DOM 트리 생성 => CSS 스타일 적용 -> Render 트리 생성 -> 레이아웃 구성 -> 페이팅 -> 화면에 표시 순서이다.

 

- 브라우저가 HTML을 전달 받으면, 곧 이를 변환(파싱)하고 노드들로 이루어진 DOM 트리를 만든다.

- 그 후, 외부의 CSS 파일과 각 노드들의 inline 스타일을 파싱하여 스타일을 입힌 Render 트리를 만든다.

- Render 트리가 만들이지면, 각 노드들이 화면에서 정확히 어디에 나타나야 하는지에 대한 위치가 주어진다.

- 그 후, paint() 메서드를 호출하면 내가 구현하고 싶었던 화면이 출력된다.

- DOM은 해당 과정을 계속 반복한다.

- 즉, 오타 수정, 문구 제거 혹은 이미지를 첨부하는 사소한 일을 하더라도, DOM은 처음부터 다시 HTML을 파싱하여 DOM 트리를 만들고 CSS를 파싱하여 Render 트리를 만들고, 레이아웃을 입혀 출력한다.

4. 자바스크립트로 태그 및 텍스트 추가

- window.onload = function() {};는 문서가 다 로딩된 다음에 함수가 실행되는 이벤트이다.

- 태그를 만들기 위해서는 document.createElement("태그이름"); 으로 변수에 넣어주면 태그가 만들어진다.

- 텍스트 노드를 만들기 위해서는 document.createTextNode("쓸 내용"); 으로 변수에 넣어주면 텍스트가 만들어진다.

- 이제 태그랑 텍스트 노드를 연결해주면 태그 안에 텍스트가 쓰여져 있는 태그가 만들어진다.
- 만든태그객체.appendChild(텍스트노드객체); 해주면 만든 태그 안에 자식으로 텍스트 노드가 들어가지게 된다. 

- 그리고 document.body.appendChild(만든태그객체); 를 해주게 되면 body의 자식 태그로 들어가서 실제로 보이게 된다.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8"/>
    </head>
    <body>
        <h2>문서 객체 모델(DOM)</h2>

        <h2>정적 객체 문서</h2>
        
        <p>이것은 문서가 로딩되기 전 이미 만들어진 "정적" 테스트 입니다.</p>
    </body>
</html>
<script>
    // 그냥 하면 문서가 로딩되기 전에 실행됨
    // alert("시작입니다.");
    // 문서가 모두 로딩된 후에 실행된다.
    window.onload = function() {
        // alert("로드가 완료되었습니다.");
        // <h2></h2> 요소를 만든다.
        const header = document.createElement("h2");
        const text1 = document.createTextNode("동적 객체 문서");

        // <h2>에 text를 연결(삽입)하다.
        header.appendChild(text1);
        
        // <body> 문서 하위로 <h2>를 문서 객체로 삽입한다.
        document.body.appendChild(header);
    
        // <p> 요소를 생성하고 텍스트를 연결한다.
        const para = document.createElement("p");
        const text2 = document.createTextNode('이것은 실행중 자바스크립을 통해 작성한 "동적" 텍스트 입니다.');

        para.appendChild(text2);

        // <body> 문서 하위로 객체 삽입
        document.body.appendChild(para);
    }
</script>