DOM(문서 객체 모델)이란

웅평·2024년 5월 13일

DOM (문서 객체 모델)이란?

문서 객체 모델(The Document Object Model, 이하 DOM) 은 HTML, XML 문서의 콘텐츠 및 구조, 그리고 스타일 요소를 구조화 시켜 표현하여 프로그래밍 언어가 해당 문서에 접근하여 읽고 조작할 수 있도록 API를 제공하는 일종의 interface이다.
DOM은 문서의 구조화된 표현(structured representation)을 제공하며 프로그래밍 언어가 DOM 구조에 접근할 수 있는 방법을 제공하여 그들이 문서 구조, 스타일, 내용 등을 변경할 수 있게 돕는다.
즉 자바스크립트 같은 스크립팅 언어가 쉽게 웹 페이지에 접근하여 조작할 수 있게끔 연결시켜주는 역할을 담당한다.

DOM은 HTML을 위한 API이면서 HTML을 탐색할 수 있고 HTML의 구조를 바꿀 수도 있다
DOM 은 웹 페이지의 객체 지향 표현이며, 자바스크립트와 같은 스크립팅 언어를 이용해 DOM을 수정할 수 있다.
우리가 JavaScript로 구현한 모든 동작들이 대체로 DOM을 수정하기 위한 것이었다.

JavaScript는 브라우저가 읽고 어떤 작업을 할 수 있는 언어.
DOM은 바로 이 작업이 이루어지는 장소인 것이다.
우리가 "JavaScript로 하는 것" 이라고 생각하는 것은 정확히는 "DOM API"이다.

DOM은 어떻게 생겼을까?

DOM은 웹 페이지, 즉 HTML 문서를 계층적 구조와 정보로 표현하며, 이를 제어할 수 있는 프로퍼티와 메서드를 제공하는 트리 자료구조이기도 합니다. 따라서 HTML DOM, 혹은 HTML DOM Tree로 부르기도 한다.

트리 자료구조는 노드들의 계층 구조로 이루어져 있습니다. 계층 구조로 이루어져 있기 때문에 부모-자식 관계, 형제관계를 표현하는 비선형 자료구조를 나타낸다.
트리 자료 구조로 구축이 되기 때문에, HTML 문서는 최종적으로 하나의 최상위 노드(root 노드)에서 시작해 자식 노드들을 가지며, 아래로만 뻗어나가는 구조로 만들어지게 된다.

출처:https://www.tcpschool.com/javascript/js_dom_concept

이러한 DOM은 W3C의 표준 객체 모델이며, 다음과 같이 계층 구조로 표현

코드로 보는 예시

<!DOCTYPE html>
<html>
  <head>
    <meta charset = "UTF-8">
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <ul>
      <li id="apple">Apple</li>
      <li id="banana">Banana</li>
      <li id="orange">Orange</li>
    </ul>
    <script src="app.js"></script>
  </body>
</html>

DOM은 HTML이 아니다

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

DOM은 눈에 보여지는 것이 아니다.

브라우저 뷰 포트에 보이는 것은 렌더 트리로 DOM과 CSSOM의 조합이다.

렌더 트리는 오직 스크린에 그려지는 것으로 구성되어 있어 DOM과 다르다.

달리 말하면, 렌더링 되는 요소만이 관련 있기 때문에 시각적으로 보이지 않는 요소는 제외된다.

내가 작성한 HTML 코드가 브라우저에 의해 파싱되면 DOM이 된다.

얼추 브라우저 개발자 툴에서 보이는 것이 바로 DOM이기 때문에 나의 HTML 코드와 동일할 수는 있지만, 대개는 달라지게 되며 개발자 툴에서는 이러한 변경 사항이 적용되어 표시된다.

예를 들어 내가 작성한 HTML에 실수가 있었고, 브라우저가 이를 대신 고친 경우에 변경 사항이 적용된다.
(자동 교정 Autocorrection)

또한, 자바스크립트로 DOM을 조작하는 경우에도 DOM과 HTML이 달라지게 된다.

요약하자면,
DOM은 HTML 문서에 대한 인터페이스다.
첫째로 뷰 포트에 무엇을 렌더링 할지 결정하기 위해 사용되며,
둘째로는 페이지의 콘텐츠 및 구조, 그리고 스타일이 자바스크립트 프로그램에 의해 수정되기 위해 사용된다.

DOM은 원본 HTML 문서 형태와 비슷하지만 몇 가지 차이점이 있다.

  • 항상 유효한 HTML 형식이다.
  • 자바스크립트에 수정될 수 있는 동적 모델이어야 한다.
  • 가상 요소를 포함하지 않는다. (Ex. ::after)
  • 보이지 않는 요소를 포함한다. (Ex. display: none)

DOM API

Javascript는 DOM에 직접 관여할 수 있다. (createElement, appendChild 등)

Javascript를 통해 DOM의 노드들을 탐색할 수도 있다.(querySelector, getElementById 등)

그 이유는 DOM이 DOM을 탐색하고 조작할 수 있는 DOM API를 제공하기 때문이다.

javascript 코드가 DOM API를 통해 DOM이나 CSSOM을 변경하면, DOM과 CSSOM은 다시 결합하여 렌더트리를 형성하고 렌더트리를 기반으로 브라우저에 다시 렌더링 된다.

node란 무엇인가?

tree 구조에서 root 노드를 포함한 모든 개개의 개체를 node라고 표현한다. head, body, title, script, h1, HEADER-1 등의 태그뿐 아니라 태그 안의 텍스트나 속성 등도 모두 node에 속한다. 이중 HTML 태그를 요소노드(Element Node)라고 부르고 요소 노드 안에 있는 글자를 Text 노드(Text Node)라고 부르기도 한다.

document node (문서 노드)

DOM Tree에서 최상위 루트 노드를 나타내며, document 객체를 가리킨다. HTML 문서 전체를 나타내는 노드이기도 한다다. window 객체의 document 프로퍼티로 연결이 되어 있어 window.document , document로 참조해 사용할 수 있습니다. HTML 문서에 이 문서 노드는 오로지 1개만 존재한다.

element node (요소 노드)

모든 HTML 요소 (body, h2, div 등)는 이 요소 노드이다. 속성 노드를 가질 수 있는 유일한 노드로서, 부모-자식 관계를 가지게 되기 때문에 계층적 구조를 이룰 수 있게 된다.

attribute node (속성 노드)

모든 HTML 요소의 속성은 이 속성 노드이다. 요소 노드에 대한 정보를 가지고 있습니다. 그렇기 때문에 부모 노드가 아닌 해당 노드와 연결이 되어 있다.

text node (텍스트 노드)

HTML 문서의 모든 텍스트는 이 텍스트 노드라 해도 과언이 아니다. 텍스트 노드는 정보를 표현하며, 가장 마지막에 위치하는 자식 노드이기 때문에 잎사귀를 닮았다 해 리프 노드라고 불리기도 한다.

이 4가지 노드들이 존재함으로써 스크립팅 언어가 웹페이지에 접근하고 조작할 수 있게 된다. 특히 데이터 검색하기가 빠른 트리 구조로 이뤄져 있기 때문에 이 접근하고 조작하여 업데이트를 하는 속도는 빠른 편이다.

DOM을 사용하는 하는 이유?

자바스크립트를 통해 HTML에서 데이터를 가져오고 싶을 때
웹 페이지 데이터를 동적으로 변경하고 싶을 때
ineractive 한 웹 애플리케이션(Web App)을 만들고 싶을 때

우리는 DOM을 사용한다.

DOM에 접근하는 방법

단수 객체 접근 : getElementByxx(), querySelector() 사용

복수 객체 접근 : getElements(), querySelectorAll() 사용

1개의 DOM Element는 다음과 같이 Tagname, Id, ClassName, CSSSelector를 통해 가져올 수 있다.

// TagName으로 찾기

document.getElementsByTagName('input') 



// ID로 찾기

document.getElementById('search') // ID는 유일값이기 때문에 가장 빠르게 찾아올 수 있다.



// ClassName으로 찾기

document.getElementsByClassName('search-input-style')



// CSSSelector로 찾기

document.querySelector('.search-input-style') // 일치하는 가장 첫 Element만 가져온다.

document.querySelectorAll('.search-input-style') // 일치하는 모든 Element를 가져온다.

그래서 DOM은 HTML을 위한 API이면서 HTML을 탐색할 수 있고 HTML의 구조를 바꿀 수도 있습니다.

DOM을 변경하는 방법
ES6의 Template Literals 문법을 참조해보자.

html template과 data를 결합해서 만들어 내는데 유용하니 꼭 참조할 것.

주요DataTypes
documentmember 가 document type 의 object 를 리턴할 때(예를 들어 element의 ownerDocument property 는 그것이 속해 있는 document 를 return 한다. ), 이 object 는 root document object 자체이다. 는 document object 에 대한 설명은 DOM document Reference 챕터를 참조하라.
elementelement 는 DOM API 의 member 에 의해 return 된 element 또는 element type 의 node 를 의미한다. document.createElement() method 가 node 를 참조하는 object 를 리턴한다고 말하는 대신, 이 method 가 DOM 안에서 생생되는 element 를 리턴한다고 좀 더 단순하게 말할 수 있다. element 객체들은 DOM Element interface 와 함께 좀 더 기본적인 Node interface 를 구현한 것이기 때문에 이 reference 에는 두 가지가 모두 포함되었다고 생각하면 된다.
nodeListnodeList 는 elements 의 배열이다. (document.getElementsByTagName() method 에 의해 리턴된 것과 같은) nodeList의 Items 은 index 를 통해 접근 가능하며, 다음과 같이 두 가지 방식이 있다: list.item(1) list[1] 위의 방식들은 동일한 것이다. item()method는 nodeList object 의 단일 method 이다. 두번째 방식은 list 에서 두번째 item 을 fetch 하는 전형적인 array syntax 이다.
attributeattribute 가 member 에 의해 리턴되는 것은(예를 들어 createAttribute() method 호출에 의한 리턴), attribute 에 대한 특별한 인터페이스를 노출하는 object reference 이다. attributes 는 DOM 에서 elements 와 같은 nodes 이다. elements 만큼 많이 사용되지는 않는다.
namedNodeMapnamedNodeMap 는 array 와 유사하지만 items 은 name 또는 index 에 의해 접근 가능하다. 리스트는 특별한 정렬이 적용되지 않았기 enumeration 할 때 index 를 주로 사용한다. namedNodeMap 는 이를 위해 item() method 가 있으며, namedNodeMap 에 item 을 추가하거나 삭제할 수 있다.

DOM의 핵심 인터페이스

실제 코드 작성 시 자주 사용되는 인터페이스들을 요약해보았다.

document.getElementById(id)
document.getElementsByTagName (en-US)(name)
document.createElement(name)
parentNode.appendChild (en-US)(node)
element.innerHTML (en-US)
element.style (en-US).left
element.setAttribute (en-US)
element.getAttribute
element.addEventListener (en-US)
window.content (en-US)
window.onload (en-US)
window.dump (en-US)
window.scrollTo (en-US)

참고
https://developer.mozilla.org/ko/docs/Web/API/Document_Object_Model/Introduction
https://www.codestates.com/blog/content/dom-javascript
https://www.tcpschool.com/javascript/js_dom_concept
https://geniee.tistory.com/32
https://velog.io/@sj_dev_js/HTML-DOM%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C

0개의 댓글