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가 nav, news-contents, footer 인 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>이다.
'♻️ 개발자로 재활용 > 🟢 JavaScript' 카테고리의 다른 글
클래스(Class)와 인스턴스(Instance) (0) | 2022.11.18 |
---|---|
일급객체(first-class citizen)와 고차함수(higher-order function) (0) | 2022.11.18 |
Spread Syntax / Rest Parameter (0) | 2022.11.13 |
JavaScript Koans (1) : 연산자와 변수, 호이스팅 (0) | 2022.11.09 |
함수가 선언된 어휘적 환경, 클로저 Closure (0) | 2022.11.08 |