♻️ 개발자로 재활용/🟢 JavaScript

DOM : 문서 객체 모델의 기본 개념

BuleRatel 2022. 11. 13. 23:47

DOM문서 객체 모델(Document Object Model)의 약자로, HTML요소를 Object(JS Object)처럼 조작(Manipulation)할 수 있는 Model이다. 즉, JS를 사용할 수 있으면 DOM으로 HTML을 조작할 수 있다. 이 객체 모델은 문서 내 모든 요소를 정의하고, 각각의 요소에 접근하는 방법을 제공한다.

웹페이지를 만들 때 토대가 되는 HTML파일, 스타일을 꾸미는 CSS 파일, 상호작용하는 JS파일을 만든다. CSS와 JS파일을 어떻게 HTML과 연결시켰을까?

<!DOCTYPE html>
<html>
	<head>
		...
	    <link rel="stylesheet" href="./yourStyle.css"> 
		<!-- CSS 파일 가져오기 -->
	</head>
	<body>
		...
		<script src='./script.js'></script>
		<!-- JS 파일 가져오기 -->
	</body>
</html>

웹 브라우저가 작성된 코드를 해석하는 과정에서 <script> 요소를 만나면, 웹브라우저는 HTML 해석을 잠시 멈추고 <script> 요소를 먼저 실행한다. 즉, <script> 요소는 등장과 함께 실행된다.

<script> 요소는 사실 </html> 태그 앞이라면 어디에 넣어도 동작을 한다. 하지만 웹브라우저는 <script>를 등장과 함께 실행하기 때문에, 무거운 스크립트가 포함되어 있으면 로딩이 느려진다. 또한 문서의 DOM 구조가 완료되기 전에 실행되어 로드 이벤트를 불러올 수 없기도 하다. 때문에 특별한 이유가 없다면 <script> 요소의 위치는 </body>가 끝나기 전 추가한다. 참고로 CSS는 가능한 빨리 적용되어 사람들에게 시각적으로 보여져야 하기 때문에 <head> 사이에 위치시키는 것이 좋다. 위의 코드 예시를 다시 보자!

 

 


DOM의 구조

HTML DOM은 노드(node)에 정보를 저장하고 있다. 위와 같은 자료 구조를 컴퓨터 공학에서는 트리 구조라고 한다. 트리 구조의 가장 큰 특징은 부모가 여러 자식을 가지고, 부모가 하나인 구조가 반복된다는 점이다.

 

  • 노드(Node) : 트리를 구성하는 기본 요소, 계층적 단위. 키 또는 값과 하위 노드에 대한 포인터를 가지고 있다.
  • 문서 노드(document node) : HTML 문서 전체를 나타내는 노드이다.
  • 요소 노드(element node) : 모든 HTML 요소는 요소 노드이며, 속성 노드를 가질 수 있는 유일한 노드이다.
  • 속성 노드(attribute node) : 모든 HTML 요소의 속성은 속성 노드이며, 요소 노드에 대한 정보를 가지고 있다. 하지만 해당 요소 노드의 자식 노드에는 포함되지 않음.
  • 텍스트 노드(text node) : HTML 문서의 모든 텍스트는 텍스트 노드이다.

 

  • 루트 노드(root node) : 트리 구조에서 부모가 없는 최상위 노드. 단 하나만 존재 (위의 예시에서 html)
  • 부모 노드(parent node) : 자식을 가진 부모 노드. 하위에 자식 노드를 가질 수 있다. (위의 li들의 부모 노드는 ul)
  • 자식 노드(child node) : 부모 노드에 하위 노드. 하위에 자식 노드를 가질 수 있으나, 부모 노드는 단 하나만 가질 수 있다. (h1과 ul은 div라는 같은 부모를 가진 자식 노드)

 

 


문제풀이로 실습하기

<html>
  <body>
    <div id="nav">
      <div class="logo"></div>
      <div class="menu-wrapper">
        <div class="menu"></div>
        <div class="menu"></div>
        <div class="menu"></div>
        <div class="profile-photo"></div>
      </div>
    </div>
    <div id="news-contents">
      <div class="news-content-wrapper">
        <div class="news-picture"></div>
        <div class="news-title"></div>
        <div class="news-description"></div>
      </div>
    </div>
    <div id="footer"></div>
  </body>
</html>

 

📌 위 HTML 문서에서 body 요소의 자식 요소(element)는 총 몇 개일까?

보이는 코드에서 하나하나 셀 수도 있겠지만, 컴퓨터에게 이 사실을 전달하기는 어렵다. JS에서 DOM 객체는 document 객체에 구현되어 있다. 콘솔을 이용해 document 객체를 조회해 보자. (참고로 console.dir를 이용하면 DOM을 객체의 모습으로 출력한다.)

console.dir(document.body)
// body를 콘솔로 출력한다.

console.dir(document.body.children)
// body의 자식 요소를 콘솔로 출력한다.

document.body.children
// body의 자식 요소를 조회한다.

위의 코드로 확인한 콘솔로그

콘솔의 결과는 위와 같다. body의 자식 요소는 id가 navnews-contentsfooter 인 3가지 요소이다.

 

 

📌 위 HTML 문서에서 id의 이름이 news-contents인 요소의 부모 요소는 무엇일까?

1번 문제를 보면, document.body.children으로만 조회했을 때 body의 자식 요소가 배열의 형태로 나타나는 것을 볼 수 있다. document 객체에도 동일하게 적용이 가능하다. news-contents는 [1]번 인덱스에 들어있으므로, 다음과 같이 부를 수 있다.

console.dir(document.body.children[1])
// body의 자식 요소의 첫번째 인덱스를 콘솔로 출력한다.

위의 코드로 확인한 콘솔로그

id의 이름이 news-contents인 요소의 주소가 ‘document.body.children[1]’임을 알았다. 이 요소의 부모 요소를 찾는 속성은 무엇일까? MDN을 참고하니 Node.parentElement을 사용하라고 한다(참고링크).

그 전에, document.body.children[1]을 조회할 때마다 모든 글자를 입력하고 주소를 찾아가는 일은 제법 번거롭다. document로 조회한 주소도 변수로 선언할 수 있으니, 다음과 같이 찾아가 보자.

let newContents = document.body.children[1]
// id가 news-contents인 요소의 주소를 변수로 선언

console.dir(newContents.parentElement)
// 해당 주소의 부모 요소를 찾아서 출력

위의 코드로 확인한 콘솔로그

console로 확인한 id news-contents인 요소의 부모 요소는 <body></body>이다.