DOM 조작
**DOM(Document Object Model)**은 브라우저가 HTML 문서를 해석해서 만든 객체 형태의 구조다. HTML의 각 태그가 하나의 객체(노드)가 되고, 이 객체들은 부모-자식 관계로 이어진 트리 구조를 이룬다.
<body>
<div id="app">
<h1>제목</h1>
<p>내용</p>
</div>
</body>위 HTML은 대략 다음과 같은 트리 구조로 표현된다.
body
└── div#app
├── h1
└── pJS는 이 DOM 객체에 접근해서 값을 읽거나, 내용을 바꾸거나, 요소를 새로 추가/삭제할 수 있다.
요소 선택하기
querySelector / querySelectorAll — 요즘 가장 많이 쓰는 방식
CSS 선택자 문법을 그대로 사용할 수 있어서 직관적이다.
// 일치하는 첫 번째 요소 하나만 선택
const title = document.querySelector("h1");
const app = document.querySelector("#app"); // id로 선택
const item = document.querySelector(".item"); // class로 선택
// 일치하는 모든 요소를 NodeList로 선택
const items = document.querySelectorAll(".item");
items.forEach((item) => console.log(item.textContent));getElementById / getElementsByClassName / getElementsByTagName — 예전부터 쓰이던 방식
const app = document.getElementById("app"); // 단일 요소 반환
const items = document.getElementsByClassName("item"); // HTMLCollection 반환
const divs = document.getElementsByTagName("div"); // HTMLCollection 반환querySelector와의 차이는, getElementsByClassName처럼 복수형 메서드가 반환하는 HTMLCollection은 실시간으로 DOM 변화를 반영하는 살아있는(live) 컬렉션이라는 점이다. 반면 querySelectorAll이 반환하는 NodeList는 선택 시점의 스냅샷이라 이후 DOM이 바뀌어도 갱신되지 않는다.
querySelector / querySelectorAll을 기본으로 사용을 권장 한다. CSS 선택자 문법 하나로 id, class, 속성, 자식 관계 등 다양한 조건을 표현할 수 있어서 일관성이 좋다.
요소 생성 / 추가 / 삭제
createElement / createTextNode — 요소와 텍스트 노드 만들기
const span = document.createElement("span");
const txt = document.createTextNode("gori");append — 맨 마지막에 삽입
노드와 텍스트를 구분 없이 한 번에 여러 개 넣을 수 있다.
container.append(span, "gori");remove — 본인을 대상으로 삭제
container.lastElementChild.remove();insertAdjacentElement / insertAdjacentHTML — 원하는 위치에 추가 (가장 많이 사용)
기준 요소를 중심으로 “어디에” 넣을지 문자열로 지정한다.
<!-- beforebegin -->
<div>
<!-- afterbegin -->
(여기 자식들)
<!-- beforeend -->
</div>
<!-- afterend -->HTML 문자열은 insertAdjacentHTML, 만든 요소는 insertAdjacentElement, 텍스트만 넣을 땐 insertAdjacentText.
replaceWith — 요소를 통째로 교체
const item1 = chks[0].parentElement;
const item2 = chks[1].parentElement;
item1.replaceWith(item2);요소 내용 / 속성 다루기
textContent / innerHTML
el.textContent = "gori"; // 순수 텍스트
el.innerHTML = "<b>gori</b>"; // HTML로 해석됨사용자 입력값처럼 신뢰할 수 없는 데이터는 innerHTML에 그대로 넣으면 XSS 위험이 있으니 textContent를 사용한다.
getAttribute / setAttribute / removeAttribute
link.getAttribute("href");
link.setAttribute("href", "/gori");
link.removeAttribute("target");
link.href = "/gori"; // 자주 쓰는 속성은 객체 속성처럼 직접 접근도 가능dataset — data-* 커스텀 속성
<div id="user" data-name="gori"></div>console.log(user.dataset.name); // "gori"
user.dataset.city = "서울"; // data-city="서울" 추가됨스타일 다루기
style — 인라인 스타일
el.style.color = "blue";
el.style.fontSize = "20px"; // camelCase로 접근classList — 클래스 추가/삭제/토글
el.classList.add("active");
el.classList.remove("active");
el.classList.toggle("active");
el.classList.contains("active"); // boolean 반환실전 예시 — 버튼 클릭 시 스타일 전환
.hidden { display: none; }toggleBtn.addEventListener("click", () => {
box.classList.toggle("hidden");
});