frontend/javascript

🟨 2-13. 자바스크립트 DOM 완전 이해 — HTML 문서를 제어하는 핵심 원리와 실전 예제

mirabo01 2025. 11. 7. 08:52

1. DOM이란 무엇인가

DOM (Document Object Model)
HTML 문서를 트리(Tree) 구조로 표현한 객체 모델이다.

즉, 브라우저는 HTML을 단순한 텍스트로 두지 않고
각 요소를 객체화하여 메모리에 저장한다.

이렇게 만들어진 구조를 자바스크립트로 접근하고 조작할 수 있다.

예를 들어,
아래 HTML이 있다면 👇

<div id="app">
  <h1>안녕하세요</h1>
  <p class="text">DOM을 배워봅시다</p>
</div>

이건 자바스크립트 내부에서 이렇게 인식된다 👇

Document
 └── div#app
      ├── h1
      └── p.text

즉, HTML은 브라우저가 객체 트리로 바꿔놓은 구조다.


2. DOM 접근하기

DOM 요소를 조작하기 위한 대표적인 선택자 메서드는 다음과 같다.

메서드 설명 예시

document.getElementById() ID로 선택 getElementById("app")
document.querySelector() CSS 선택자 1개 선택 querySelector(".text")
document.querySelectorAll() CSS 선택자 여러 개 선택 querySelectorAll("p")
document.getElementsByClassName() 클래스명으로 선택 getElementsByClassName("text")

예시 👇

const app = document.getElementById("app");
const paragraph = document.querySelector(".text");

console.log(app.innerHTML);
console.log(paragraph.textContent);

✅ innerHTML → HTML 구조 포함
✅ textContent → 순수 텍스트만


3. DOM 내용 변경

HTML 요소의 내용을 동적으로 바꿀 수 있다.

const title = document.querySelector("h1");
title.textContent = "Hello, DOM!";

또는 태그 자체를 바꾸고 싶다면 👇

title.innerHTML = "<span style='color:red'>DOM 조작 성공!</span>";

✅ innerHTML 은 HTML 태그를 파싱해 렌더링함
✅ textContent 는 단순 문자열 변경


4. DOM 속성 제어

HTML 속성(attribute)은 setAttribute() / getAttribute()로 관리할 수 있다.

const link = document.createElement("a");
link.setAttribute("href", "https://jisiknarae.com");
link.textContent = "지식나래 방문하기";
document.body.appendChild(link);

console.log(link.getAttribute("href")); // "https://jisiknarae.com"

✅ 또는 점(.) 표기법으로 바로 접근 가능

link.href = "https://blog.jisiknarae.com";

5. DOM 스타일 변경

DOM 요소의 CSS 속성도 자바스크립트로 조작할 수 있다.

const box = document.querySelector("#box");
box.style.width = "200px";
box.style.backgroundColor = "skyblue";
box.style.borderRadius = "10px";

✅ CSS 속성 이름은 camelCase로 변환해야 한다.
예: background-color → backgroundColor


6. DOM 요소 추가 및 삭제

새로운 요소를 만들고 문서에 삽입하거나 제거할 수도 있다.

const list = document.querySelector("ul");
const newItem = document.createElement("li");
newItem.textContent = "새로운 항목 추가";
list.appendChild(newItem);

✅ appendChild() → 마지막에 추가
✅ prepend() → 맨 앞에 추가
✅ remove() → 요소 삭제

newItem.remove();

7. 이벤트 등록

DOM 조작의 진짜 매력은 이벤트 기반 상호작용이다.

const button = document.querySelector("#btn");
button.addEventListener("click", () => {
  alert("버튼이 클릭되었습니다!");
});

✅ addEventListener(이벤트명, 콜백)
✅ 콜백 함수 안에서 this 또는 event.target으로 대상 접근 가능

button.addEventListener("mouseover", (e) => {
  e.target.style.backgroundColor = "orange";
});

8. 이벤트 위임 (Event Delegation)

여러 요소에 각각 이벤트를 붙이지 않고,
상위 요소에서 하위 요소의 이벤트를 “위임”받는 방식이다.

document.querySelector("ul").addEventListener("click", (e) => {
  if (e.target.tagName === "LI") {
    console.log("클릭된 항목:", e.target.textContent);
  }
});

✅ 리스트처럼 동적으로 생성되는 요소에도 반응 가능
✅ React의 이벤트 버블링도 같은 원리다.


9. DOM 조작의 성능 이슈

DOM은 실제 렌더링 트리와 연결되어 있어,
무분별한 조작은 브라우저 성능 저하를 유발한다.

❗ DOM 접근은 느리고, 변경이 많을수록 리렌더링 비용이 커진다.

💡 해결 방법

  • DocumentFragment 로 임시 DOM 구성 후 한 번에 삽입
  • 반복 변경 시 innerHTML보다 textContent 사용
  • React, Vue 등은 이런 성능 문제를 해결하기 위해 “Virtual DOM”을 도입했다.

10. 실전 예제 — 동적 목록 추가

<input id="todoInput" placeholder="할 일을 입력하세요" />
<button id="addBtn">추가</button>
<ul id="todoList"></ul>

<script>
const input = document.getElementById("todoInput");
const list = document.getElementById("todoList");
const btn = document.getElementById("addBtn");

btn.addEventListener("click", () => {
  const text = input.value.trim();
  if (!text) return alert("내용을 입력하세요!");
  
  const li = document.createElement("li");
  li.textContent = text;
  list.appendChild(li);
  input.value = "";
});
</script>

✅ HTML 입력 → JS DOM 생성 → 즉시 반영
✅ 가장 기본적이면서 강력한 DOM 실습 예제다.


11. 정리

개념 설명

DOM HTML 문서를 객체 트리로 표현한 구조
선택자 querySelector, getElementById 등
조작 innerHTML, setAttribute, style
이벤트 addEventListener로 사용자 입력 감지
성능 관리 Virtual DOM, Fragment로 최적화

12. 마무리

이제 HTML과 CSS를 넘어,
자바스크립트가 어떻게 “문서를 살아 움직이게 하는지” 완전히 이해했다.

DOM은 모든 프론트엔드 프레임워크의 뿌리이며,
한 번만 제대로 이해해두면 React나 Vue의 작동 원리도 명확하게 보인다.

“DOM을 이해한 사람은, 프레임워크를 선택할 때 흔들리지 않는다.”