Lesson 14

DOM 이해하기

3 min Views 1

DOM 트리 구조를 이해하고 요소를 선택·생성·수정·삭제하는 방법을 배운다. style과 classList 조작, 속성 접근, 그리고 효율적인 DOM 조작 패턴을 익힌다.

DOM이란?

DOM(Document Object Model)은 HTML 문서를 트리 구조의 객체로 표현한 것입니다. 자바스크립트는 이 DOM을 통해 HTML 요소를 읽고, 변경하고, 추가하고, 삭제할 수 있습니다. 브라우저가 HTML을 파싱하면 DOM 트리가 생성되고, 자바스크립트는 이 트리를 조작합니다.

HTML:
<div id="app">
  <h1 class="title">제목</h1>
  <p>단락</p>
</div>

DOM 트리:
document
  └── html
        ├── head
        └── body
              └── div#app
                    ├── h1.title ("제목")
                    └── p ("단락")

요소 선택

// querySelector — CSS 선택자로 첫 번째 일치 요소
document.querySelector("#app")         // id="app"
document.querySelector(".title")       // class="title" 중 첫 번째
document.querySelector("h1")           // h1 태그 첫 번째
document.querySelector(".list li:first-child")
document.querySelector("[data-id]")    // data-id 속성 있는 요소

// querySelectorAll — 모두 선택 (NodeList 반환)
const items = document.querySelectorAll(".item");
items.forEach(el => console.log(el.textContent));
[...items].map(el => el.textContent); // 배열로 변환

// 구식 메서드 (여전히 빠름)
document.getElementById("app")
document.getElementsByClassName("title") // HTMLCollection
document.getElementsByTagName("div")

// 범위 제한: 특정 요소 내에서만 검색
const container = document.querySelector("#container");
container.querySelector(".item"); // container 안에서만

요소 내용 읽기/수정

const el = document.querySelector("h1");

// 텍스트
el.textContent    // 모든 텍스트 (자식 포함), HTML 태그 제거
el.textContent = "새 제목"; // 설정 시 HTML 이스케이프됨 (안전)

// HTML (XSS 주의!)
el.innerHTML      // 내부 HTML 문자열
el.innerHTML = "<strong>굵게</strong>"; // HTML로 파싱

// outerHTML — 요소 자체 포함
el.outerHTML      // "<h1>제목</h1>"

속성 조작

const link = document.querySelector("a");

// 속성 읽기/쓰기
link.getAttribute("href")           // 속성값 반환
link.setAttribute("href", "https://example.com")
link.removeAttribute("target")
link.hasAttribute("disabled")       // true/false

// DOM 프로퍼티 (더 빠름)
link.href         // 전체 URL
link.id           // id 값
link.className    // class 문자열

// data-* 속성 — dataset
// HTML: <div data-user-id="42" data-role="admin">
const div = document.querySelector("div");
div.dataset.userId    // "42" (camelCase 자동 변환)
div.dataset.role      // "admin"
div.dataset.newProp = "value"; // 추가

클래스 조작 — classList

const el = document.querySelector(".box");

el.classList.add("active");           // 추가
el.classList.remove("hidden");        // 제거
el.classList.toggle("dark");          // 있으면 제거, 없으면 추가
el.classList.toggle("active", true);  // 두 번째 인자로 강제
el.classList.contains("active");      // true/false
el.classList.replace("old", "new");   // 교체
[...el.classList]                     // 배열로 변환

// className은 문자열 전체 (덮어씀 위험)
el.className = "box active"; // 기존 클래스 모두 덮어씀

스타일 조작

const el = document.querySelector(".box");

// 인라인 스타일 설정
el.style.backgroundColor = "#ff0000"; // camelCase!
el.style.fontSize = "16px";
el.style.display = "none";
el.style.cssText = "color: red; font-size: 20px;"; // 여러 개 한번에

// 계산된 스타일 읽기 (CSS 파일 포함)
const computed = getComputedStyle(el);
computed.color          // "rgb(0, 0, 0)"
computed.fontSize       // "16px"
computed.display        // "block"

요소 생성 및 추가

// 요소 생성
const newDiv = document.createElement("div");
newDiv.textContent = "새로운 요소";
newDiv.className = "card";
newDiv.setAttribute("data-id", "1");

// 삽입
const container = document.querySelector("#container");
container.appendChild(newDiv);          // 마지막 자식으로
container.prepend(newDiv);              // 첫 번째 자식으로
container.after(newDiv);                // container 뒤에

// innerHTML로 여러 요소 한번에 (XSS 주의)
container.innerHTML = `
  <div class="card"><h3>제목</h3><p>내용</p></div>
`;

// insertAdjacentHTML (기존 내용 유지)
container.insertAdjacentHTML("beforeend", "<p>추가</p>");
// beforebegin, afterbegin, beforeend, afterend

요소 제거 및 탐색

const el = document.querySelector(".remove-me");
el.remove(); // 제거 (Modern)

// DOM 탐색
el.parentElement          // 부모 요소
el.children               // 자식 요소들
el.firstElementChild      // 첫 번째 자식
el.lastElementChild       // 마지막 자식
el.nextElementSibling     // 다음 형제
el.previousElementSibling // 이전 형제

// 위치/크기
el.getBoundingClientRect() // { top, left, width, height }
el.offsetTop               // 부모로부터의 y 오프셋

관련 검색어  ·  DOM 조작, querySelector 사용법, classList 추가 삭제, innerHTML textContent, DOM 요소 생성, dataset 속성

채용정보
공지사항
인사이트
MY