TIL020 | 문서 객체 모델 DOM

김태규·2021년 8월 22일
0
post-thumbnail

1. DOM

문서 객체 모델(Document Object Model, DOM)은 웹 페이지 내의 모든 콘텐츠(HTML)를 계층화시켜 객체로 나타내는 모델이다.
객체의 접근방식 중 dot notation을 사용하여 document 객체에 접근하는 것으로 시작된다. 이 document 객체를 사용해서 페이지의 내용을 변경하거나 html 요소를 새로 만들거나 클래스를 부여하거나 스타일을 부여하는 등 여러가지 작업을 할 수 있다.

DOM 객체 트리 구조를 시각화한 자료이다. 각각의 태그는 요소 노드(element node) 혹은 그냥 요소라고 하며 트리 구조를 구성한다. root 노드인 html을 기준으로 head, body라는 자식 노드가 있고 나무 가지처럼(트리 구조) 계속 자식 노드들이 형성되어 있다.


2. 원하는 요소에 접근하기

document.body.style.background = 'blue';
// body 의 배경을 파랑색으로 변경

document.body로 body에 접근한 예시이다. 이처럼 document 라는 진입점에서 출발하여 원하는 요소 노드에 접근하는 대표적인 함수가 몇 가지 있다.

  • document.getElmentById()
  • document.getElementsByClassName()
  • document.getElementsByTagName()
  • document.querySelector()
  • document.querySelectorAll()

위의 함수들을 사용하여 원하는 요소에 접근한 후 해당 요소를 변경할 수 있다.

const myFirstClass = document.getElementsByClassName('myClass')[0];
const contactEmail = document.getElementById('contactEmail');

myFirstClass.innerHTML = '퍼스트 클래스' 
contactEmail.style.color = 'green'

위의 코드를 해석하면, 'myClass'라는 클래스 이름을 갖는 요소들 중 첫번째 요소에 접근한 후 '퍼스트 클래스'라는 문자를 입력했다. 그리고 'contactEmail'이라는 id 이름을 갖는 요소에 접근하여 배경색을 초록색으로 변경했다.

getElemntsByClassName 에서는 elements(복수형)이므로 'myClass' 에 해당하는 요소를 담은 컬렉션이 반환된다. 따라서 여러 개 중 첫 번째에 접근하기 위해 [0]과 같이 배열의 요소에 접근하는 것처럼 하나를 특정해야 한다. 반면 id는 고유한 값이기 때문에 getElementById 와 같이 접근하는 것 만으로 하나의 요소에 접근할 수 있다.


3. 스크립트의 위치

브라우저는 HTML을 읽다가 <script> 태그를 만나면 DOM 생성을 멈추고 스크립트를 먼저 실행한다. 이런 브라우저의 동작 순서 때문에 다음과 같은 문제가 발생한다.

  1. <script> 는 해당 스크립트 아래에 있는 DOM에 접근할 수 없게 된다.
  2. 페이지 위에 용량이 큰 스크립트 파일이 있는 경우 해당 사용자가 해당 스크립트를 다운로드 받아서 실행할 때까지 스크립트 아래의 페이지가 화면에 표시되는 것이 지연된다.

용량이 크지 않은 웹페이지의 경우, <script> 태그는 <body>의 최하단에 위치시켜 모든 컨텐츠가 다 보여지고 나서 스크립트 파일이 실행되도록 할 수 있다. 이렇게 하면 스크립트 위에 있는 요소에 접근할 수 있고, 페이지 컨텐츠 출력을 막지 않게 된다.

그런데 이 방법은 완벽한 해결책이 될 수는 없다. HTML 문서 자체가 아주 큰 경우를 가정해보면 브라우저가 HTML 문서 전체를 다운로드 한 다음에 스크립트를 다운받게 하면 페이지가 정말 느려지게 된다.

이런 문제를 해결할 수 있는 <script> 속성이 있는데, 바로 defer와 async이다.

  • defer
    브라우저는 defer 속성이 있는 스크립트(이하 defer 스크립트 또는 지연 스크립트)를 '백그라운드’에서 다운로드한다. 따라서 지연 스크립트를 다운로드 하는 도중에도 HTML 파싱이 멈추지 않고, defer 스크립트 실행은 페이지 구성이 끝날 때까지 지연된다.
<script defer src=""></script>
  • async
    async 스크립트는 defer 스크립트와 마찬가지로 백그라운드에서 다운로드된다. 따라서 HTML 페이지는 async 스크립트 다운이 완료되길 기다리지 않고 페이지 내 콘텐츠를 처리, 출력한다. 하지만 defer와 달리 async 스크립트 실행중에는 HTML 파싱이 멈춘다. 다른 스크립트들은 async 스크립트를 기다리지 않고, async 스크립트 역시 다른 스크립트들을 기다리지 않는다.
    이런 특징 때문에 페이지에 async 스크립트가 여러 개 있는 경우, 그 실행 순서가 제각각이 된다. 실행은 다운로드가 끝난 스크립트 순으로 진행된다.
<script async src="https://long.js"></script>
<script async src="https://small.js"></script>

위치상으론 small.js가 아래이긴 하지만 long.js보다 먼저 다운로드된다면 먼저 실행된다. 이렇게 먼저 로드가 된 스크립트가 먼저 실행되는 것을 'load-first order’라고 부른다.





references

https://developer.mozilla.org/ko/docs/Web/API/Document_Object_Model/Introduction
https://ko.javascript.info/script-async-defer

0개의 댓글