Learning
레슨 5 / 9·20분

DOM 조작과 이벤트

DOM 요소 선택

DOM(Document Object Model)은 HTML 문서를 JavaScript로 다룰 수 있게 하는 인터페이스입니다. querySelectorquerySelectorAll로 CSS 선택자를 사용해 요소를 찾습니다.

javascript
// 단일 요소 선택
const title = document.querySelector("h1");
const btn = document.querySelector("#submit-btn");
const first = document.querySelector(".card");

// 여러 요소 선택 (NodeList 반환)
const cards = document.querySelectorAll(".card");
cards.forEach(card => console.log(card.textContent));

// getElementById (클래식 방법)
const header = document.getElementById("header");

요소 생성, 수정, 삭제

JavaScript로 HTML 요소를 동적으로 만들고 변경할 수 있습니다. createElement로 생성하고, appendChildappend로 DOM에 추가합니다.

javascript
// 요소 생성 & 추가
const li = document.createElement("li");
li.textContent = "새 항목";
li.classList.add("item", "active");
document.querySelector("ul").appendChild(li);

// 속성 변경
const img = document.querySelector("img");
img.src = "/new-image.png";
img.alt = "새 이미지";
img.setAttribute("data-id", "42");

// 스타일 변경
const box = document.querySelector(".box");
box.style.backgroundColor = "#3b82f6";
box.style.padding = "16px";

// 요소 삭제
const old = document.querySelector(".outdated");
old.remove();

이벤트 리스너

addEventListener로 사용자 상호작용(클릭, 입력, 스크롤 등)에 반응합니다. 이벤트 객체(e)에는 대상 요소, 위치 등 유용한 정보가 담겨 있습니다.

javascript
// 클릭 이벤트
const btn = document.querySelector("#myBtn");
btn.addEventListener("click", (e) => {
  console.log("클릭됨!", e.target);
  e.target.textContent = "클릭됨!";
});

// 입력 이벤트
const input = document.querySelector("#search");
input.addEventListener("input", (e) => {
  console.log("입력값:", e.target.value);
});

// 키보드 이벤트
document.addEventListener("keydown", (e) => {
  if (e.key === "Escape") {
    console.log("ESC 키 눌림");
  }
});

// 이벤트 제거
function handleClick() { console.log("click"); }
btn.addEventListener("click", handleClick);
btn.removeEventListener("click", handleClick);

이벤트 위임

이벤트 위임(Event Delegation)은 부모 요소에 리스너를 하나만 등록하여 자식 요소의 이벤트를 처리하는 패턴입니다. 동적으로 추가되는 요소에도 작동하며 성능이 좋습니다.

javascript
// 이벤트 위임 — ul에 리스너 하나로 모든 li 처리
const list = document.querySelector("#todo-list");
list.addEventListener("click", (e) => {
  // 클릭된 요소가 삭제 버튼인지 확인
  if (e.target.matches(".delete-btn")) {
    const li = e.target.closest("li");
    li.remove();
  }

  // 체크박스 토글
  if (e.target.matches("input[type=checkbox]")) {
    const li = e.target.closest("li");
    li.classList.toggle("completed");
  }
});
💡

innerHTML로 HTML을 삽입하면 XSS 공격에 취약할 수 있습니다. 사용자 입력을 표시할 때는 textContent를 사용하세요.