DOM이란 무엇인가?

Sonny·2019년 9월 3일
20

Etc

목록 보기
4/4
post-thumbnail

웹 페이지가 만들어지는 방법

먼저 DOM을 이해하기 위해서는 웹 페이지의 빌드과정을 알아야 한다.

Critical Rendering Path

브라우저가 서버에서 페이지에 대한 HTML 응답을 받으면 화면에 표시되기 전에 많은 단계를 거쳐야 하는데 웹 브라우저가 원본 HTML 문서를 읽어들인 후, 스타일을 입히고 대화형 페이지로 만들어 뷰 포트에 표시하기까지의 과정을 Critical Rendering Path, CPR이라고 한다.

CRP의 6단계 과정

  • DOM 트리 구축
  • CSSSOM 트리 구축
  • JavaScript 실행
  • 렌더 트리 구축
  • 레이아웃 생성
  • 페인팅

image.png

위와 같이 CRP 과정은 6단계로 나누어져 있지만 대략 렌더 트리 구축을 기점으로 두 단계로 나눌 수 있다.

  • 첫번째 단계 : 브라우저는 읽어들인 문서를 파싱하여 최종적으로 어떤 내용을 페이지에 렌더링할 지 결정한다. (이 단계를 거치면 렌더 트리가 생성이 된다.)
  • 두번째 단계 : 브라우저는 해당 렌더링을 수행한다.

image.png

렌더 트리

렌더 트리란 웹 페이지에 표시될 HTML요소들과 이와 관련된 스타일 요소들로 구성된다. 브라우저는 렌더 트리를 생성하기 위해 아래와 같이 두 모델이 필요하다.

  • DOM(Document Object Model) : HTML 요소들의 구조화된 표현
  • CSSOM(Cascading Style Sheets Object Model) : 요소들과 연관된 스타일 정보의 구조화된 표현

DOM (Document Object Model)

DOM(문서 객체 모델)이란? 웹 페이지에 대한 프로그래밍 인터페이스이다. 기본적으로 여러 프로그램들이 페이지의 콘텐츠 및 구조, 그리고 스타일을 읽고 조작할 수 있는 API를 제공한다.

1. DOM의 생성 방식

DOM은 원본 HTML 문서의 객체 기반 표현 방식이며 DOM의 개체 구조는 노드 트리(하나의 부모 줄기가 여러개의 자식 나뭇가지, 나뭇잎들을 가질 수 있는 나무와 같은 구조)로 표현된다.

1.1 HTML 코드로 알아보는 노드트리

<!doctype html>
<html lang="en">
	<head>
    	<title> My first web page </title>
    </head>
    <body>
    	<h1> Hello, world! </h1>
        <p> How are you? </p>
    </body>
</html>

위의 문서는 아래와 같은 노드 트리로 표현이 된다.

image.png

2. DOM과 HTML의 차이점

DOM은 HTML 문서로부터 생성이 되지만 항상 동일하지 않다.

  • HTML : 화면에 보이고자 하는 모양과 구조를 문서로 만든 것으로 단순 텍스트로 구성되어 있다. (최초에 화면을 그릴때 사용하는 설계도)

  • DOM : HTML 문서의 내용과 구조가 객체 모델로 변화되어 다양한 프로그램에서 사용될 수 있다. (설계도를 이용하여 실제로 화면에 나타내지는 인터페이스)

2.1 DOM이 원본 HTML 소스와 다를 수 있는 두 가지 케이스

작성된 HTML 문서가 유효하지 않을 때

DOM은 유효한 HTML 문서의 인터페이스이다. DOM을 생성하는 동안, 브라우저는 유요하지 않은 HTML 코드를 올바르게 교정한다.

<!doctype html>
<html>
	Hello, world!
</html>

위의 코드에서는 문서에 유효한 HTML 규칙의 필수 사항인 <head><body>요소가 빠져있지만 아래와 같이 DOM 트리에는 올바르게 교정되어 나타난 것을 볼 수 있다.
image.png

JavaScript에 의해 DOM이 수정될 때

DOM은 HTML 문서의 내용을 볼 수 있는 인터페이스 역할을 하는 동시에 동적 자원이 되어 수정될 수 있다.

var p = document.createElement('p');
var pContent = document.createTextNode('I'm new!');
p.appendChild(pContent);
document.body.appendChild(p);

위의 코드는 JavaScript를 사용하여 DOM에 새로운 노드를 추가하는 코드이며 이 코드는 DOM을 업데이트하지만 HTML 문서의 내용을 변경하지는 않는다.

3. DOM은 브라우저에서 보이는 것이 아니다.

브라우저 뷰 포트에 보이는 것은 렌더 트리로 DOM과 CSSOM의 조합이다. 렌더 트리는 오직 렌더링 되는 요소만 관련이 있고 스크린에 그려지는 것으로 구성되어 있어 시각적으로 보이지 않는 요소들은 제외되기 때문에 DOM과는 다르다.

3.1 예시) display : none 스타일 속성을 가지고 있는 요소

<!doctype html>
<html lang="en">
	<head></head>
    <body>
    	<h1> Hello, world! </h1>
        <p style="display : none;"> How are you? </p>
    </body>
</html>

렌더 트리에 해당하는 뷰 포트에 표시되는 내용은 <p>요소를 포함하지 않으며 내용은 아래와 같다.

image.png
하지만 아래와 같이 DOM은 <p>요소를 포함시키는 것을 볼 수 있다.

image.png

4. DOM은 개발도구에서 보이는 것이 아니다.

개발도구의 요소 검사기는 DOM과 가장 가까운 근사치를 제공하지만 개발도구의 요소 검사기는 DOM에 없는 추가적인 정보를 포함한다.

4.1 예시) CSS의 가상 요소

::before::after 선택자를 사용하여 생성된 가상 요소는 CSSOM과 렌더 트리의 일부를 구성하지만 DOM은 오직 원본 HTML 문서로부터 빌드 되고, 요소에 적용되는 스타일을 포함하지 않기 때문에 기술적으로 DOM의 일부는 아니다.

가상 요소는 DOM의 일부가 아니기 때문에 JavaScript에 의해 수정될 수 없다. (다른 방법을 이용하여 수정 가능하게 할 수 있는 경우도 있다.)

image.png
가상 요소가 DOM의 일부가 아님에도 요소 검사기에서는 위와 같이 확인이 되는 것을 볼 수 있다.

CSS 선택기를 사용하여 DOM 요소를 선택하는 방법

1. querySelector를 사용하여 DOM 요소를 선택하는 방법

2. ID, Class, Tag를 사용하여 DOM 요소를 선택하는 방법

  • getElementById : 주어진 문자열과 일치하는 id속성을 가진 요소를 찾아온다.
  • getElementsByClassName : 주어진 클래스 이름을 가진 모든 자식 요소를 배열과 같은 객체로 반환한다.
  • getElementsByTagName : Element의 HTMLCollection과 주어진 태그명을 반환한다. Root node를 포함해 전체 document를 대상으로 검색된다.

3. 부모, 형제, 자식 DOM 요소를 선택하는 방법

  • parentElement : 호출된 Element의 부모 요소를 반환한다.
  • nextElementSibling : 호출된 Element의 바로 뒤에 있는 요소(형제)를 반환한다.
  • previousElementSibling : 호출된 Element의 바로 앞에 있는 요소(형제)를 반환한다.
  • children : 호출된 Element의 모든 자식을 반환한다.

DOM Elements 제어 방법

1. DOM Elemnet 생성하기

var element = document.createElement('tagName');

지정한 tagName의 HTML Element를 만들어 반환한다.

2. Add, remove, toggle를 ㅣ이용하여 class 제어하기

  • Class 추가하기 (classList.add) : 지정한 class값을 추가한다.
var addClass = element.classList.add('className');
  • Class 삭제하기 (classList.remove) : 지정한 class값을 제거한다.
var removeClass = element.classList.remove('className');
  • Class 토글 (classList.toggle) : class가 존재한다면 제거하고 존재하지 않으면 class를 추가한다.
var removeClass = element.classList.toggle('className');

3. 속성 추가하기

setAttribute 구문

지정된 속성을 Element에 추가하고 지정된 값을 제공한다.

element.setAttribute ( 'attribute' , 'value' );
  • attribute : 속성의 특정 이름을 설정한다.
  • value : 속성에 값을 할당한다.

사용 예시

var menu = document.querySelector('a');

menu.setAttribute('href','https://velog.io/@surim014');

4. Element 제거하기

remove() 구문

node를 제거한다.

node : 여러가지 DOM타입들이 상속하는 인터페이스이다.
( ex : Document, Element, CharacterData 등 )

node.remove();

사용 예시

var el = document.querySelector('div');

el.remove();

5. Element 추가하기

appendChild() 구문

특정 부모 node의 자식 node리스트 중 마지막 자식으로 붙인다.

element.appendChild(aChild);
  • element : 부모 요소
  • aChild : 지정된 부모의 밑으로 들어갈 자식 요소

사용 예시

var li = document.createElement('li');
var span = document.createElement('span');

li.appendChild(span);

DOM Events

addEventListener() 구문

EventTarget의 addEventListener() 메서드는 지정한 이벤트가 대상에 전달될 때마다 호출할 함수를 설정한다.

target.addEventListener( type, listener);
  • type (이벤트명) : 반응할 이벤트의 유형 및 이름 ( ex : 'mouseover' )
  • listenr (이벤트핸들러) : 지정된 타입의 이벤트가 발생했을 때 실행될 함수 ( ex : function (event 객체) {} )

Event 객체 소개

Event 객체란? DOM내에 위치한 이벤트를 나타내며 사용자가 현재 취한 액션에 대한 상세정보를 담고 있다.

Event.target vs Event.currentTarget

  • Event.target : 해당 이벤트가 발생한 근원지에 위치한 DOM Element를 가리킨다.
  • Event.currentTarget : addEventListener를 실행한 대상이 되는 Element를 가리킨다. (이벤트가 실제로 등록이 된 Element)

요약 정리

DOM은 HTML 문서에 대한 인터페이스이다.

DOM이 사용되는 곳

  • 뷰 포트에 무엇을 렌더링 할지 결정하기 위해 사용된다.
  • 페이지의 컨텐츠 및 구조, 그리고 스타일이 JavaScript 프로그램에 의해 수정되기 위해 사용된다.

DOM과 HTML의 차이점

  • DOM은 항상 유효한 HTML 형식이다.
  • DOM은 JavaScript에 의해 수정될 수 있는 동적 모델이어야 한다.
  • DOM은 가상 요소를 포함하지 않는다. ( Ex. ::after )
  • DOM은 보이지 않는 요소를 포함한다. ( Ex. display : none )

참고사이트

profile
FrontEnd Developer

5개의 댓글

comment-user-thumbnail
2020년 10월 16일

DOM과 렌더 트리를 이해하는데 많은 도움이 되었네요. 감사합니다.

1개의 답글
comment-user-thumbnail
2021년 6월 22일

DOM과 렌더 트리 이해하는데 많은 도움 되었습니다. 좋은 글 감사합니다!

1개의 답글