🎯
EPISODE 06
querySelector · createElement · classList · dataset
DOM 조작
DOM 요소를 선택(getElementById/querySelector), 변경(textContent vs innerHTML), 동적 추가/삭제(createElement, appendChild), classList 토글, data-* 속성을 익힙니다.
JavaScriptDOMclassList
소요 시간
⏱ 60분
난이도
📊 초보~중급
선수 조건
🎯 js-05
결과물
JavaScript로 페이지 내용을 동적으로 추가·삭제
이 강의에서 배우는 것
- 1getElementById/querySelector/querySelectorAll로 요소를 선택한다
- 2textContent와 innerHTML의 보안 차이를 안다
- 3createElement → appendChild로 요소를 동적으로 만든다
- 4classList의 add/remove/toggle/contains를 사용한다
- 5data-* 속성과 dataset으로 데이터를 저장·읽는다
1. 요소 선택
javascript
// ID로 단일 (가장 빠름)
const title = document.getElementById('title');
// CSS 선택자로 첫 번째
const btn = document.querySelector('.btn');
const input = document.querySelector('input[type="text"]');
// CSS 선택자로 모두 (NodeList)
const allItems = document.querySelectorAll('.item');
allItems.forEach(item => console.log(item.textContent));2. textContent vs innerHTML
javascript
const div = document.querySelector('#content');
// textContent: 텍스트만 (HTML 무시, 안전)
div.textContent = '<b>굵게</b>'; // "<b>굵게</b>" 그대로 표시
// innerHTML: HTML 해석
div.innerHTML = '<b>굵게</b>'; // 굵게 표시⚠️
innerHTML에 사용자 입력값을 직접 넣으면 XSS 공격 위험. 사용자 입력은 textContent를 사용하거나 별도 이스케이프 처리.
3. 요소 생성/추가/삭제
javascript
// 생성
const newDiv = document.createElement('div');
newDiv.textContent = '새 요소';
newDiv.className = 'card';
// 추가
const container = document.querySelector('#container');
container.appendChild(newDiv); // 끝
container.prepend(newDiv); // 앞
container.insertBefore(newDiv, container.firstChild);
// 삭제
container.removeChild(newDiv);
newDiv.remove(); // 모던 방식
// 부모 참조
const parent = newDiv.parentElement;4. classList
javascript
const box = document.querySelector('.box');
box.classList.add('active');
box.classList.add('highlight', 'large'); // 여러 개
box.classList.remove('active');
box.classList.toggle('dark-mode'); // 있으면 제거, 없으면 추가
if (box.classList.contains('active')) {
console.log('active!');
}5. dataset
html
<button data-id="42" data-user-name="홍길동" data-is-admin="true">
클릭
</button>javascript
const btn = document.querySelector('button');
// kebab-case → camelCase 자동 변환
console.log(btn.dataset.id); // "42"
console.log(btn.dataset.userName); // "홍길동"
console.log(btn.dataset.isAdmin); // "true" ← 항상 문자열
// 쓰기
btn.dataset.count = 0;
btn.dataset.lastClicked = Date.now();