모든 강의를 무료로 볼 수 있어요. 회원가입 없이도 학습 가능합니다.

17강 / 전체 22강

DOM 내용·스타일 변경

14분 읽기 조회 3

textContent·innerHTML로 내용 변경, classList.add/remove/toggle로 클래스 조작, style 속성으로 인라인 스타일 적용, setAttribute로 HTML 속성 변경까지 DOM 요소를 자유자재로 수정합니다.

🎯 학습 목표

이 강을 마치면 다음을 할 수 있습니다.

  • textContent와 innerHTML의 차이를 이해하고 적절히 사용할 수 있습니다.
  • classList의 add, remove, toggle, contains로 CSS 클래스를 동적으로 조작할 수 있습니다.
  • style 속성으로 인라인 스타일을 적용하고 CSS 변수와 연동할 수 있습니다.
  • setAttribute, getAttribute로 HTML 속성을 읽고 쓸 수 있습니다.

✏️ 텍스트·HTML 내용 변경

이 섹션에서는 선택한 요소의 내용을 변경하는 두 가지 핵심 속성을 살펴보겠습니다.

16강에서 DOM 요소를 선택하는 방법을 배웠습니다. 이제 선택한 요소의 내용을 실제로 바꾸는 방법을 배웁니다. 내용을 변경하는 속성은 주로 두 가지입니다. textContent와 innerHTML입니다. 이 둘은 비슷해 보이지만 중요한 차이가 있습니다.

// HTML:
// <div id="box">
//   <p>원래 내용</p>
// </div>

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

// textContent — 순수 텍스트로 설정 (HTML 태그 무시)
console.log(box.textContent);  // "\n  원래 내용\n" (공백 포함)
box.textContent = "새 텍스트";
// 결과: <div id="box">새 텍스트</div>
// 하위 요소가 모두 사라지고 텍스트만 남음

// innerHTML — HTML 마크업으로 설정
box.innerHTML = "<p><strong>강조</strong>된 새 내용</p>";
// 결과: <div id="box"><p><strong>강조</strong>된 새 내용</p></div>
// HTML이 파싱되어 실제 요소로 생성됨

console.log(box.innerHTML);    // "<p><strong>강조</strong>된 새 내용</p>"
console.log(box.textContent);  // "강조된 새 내용" (태그 제거된 순수 텍스트)

// 실전: 카운터 표시
let count = 0;
const counter = document.querySelector("#counter");

function update() {
  count++;
  counter.textContent = count;  // 숫자를 문자열로 자동 변환해 삽입
}

// 실전: 목록 렌더링
const items = ["사과", "바나나", "포도"];
const ul = document.querySelector("ul");
ul.innerHTML = items.map(item => `<li>${item}</li>`).join("");
// 배열 → HTML 문자열 변환 후 innerHTML에 할당

textContent vs innerHTML 선택 기준이 중요합니다. 순수 텍스트(숫자, 사용자 입력값 등)를 표시할 때는 항상 textContent를 사용하세요. innerHTML에 사용자 입력을 그대로 넣으면 XSS(크로스 사이트 스크립팅) 보안 취약점이 생깁니다. 예를 들어 악의적인 사용자가 <script>악성코드</script>를 입력값에 넣으면 실행될 수 있습니다. HTML 마크업을 직접 생성할 때만 innerHTML을 사용하고, 이 때도 사용자 입력은 반드시 이스케이프 처리해야 합니다. 20강에서 배울 createElement와 appendChild를 사용하면 XSS 없이 안전하게 요소를 생성할 수 있습니다.

🎨 classList — 클래스 조작

이 섹션에서는 CSS 클래스를 동적으로 추가·제거·토글하는 classList API를 살펴보겠습니다.

동적인 UI에서 요소의 외양을 바꾸는 가장 좋은 방법은 CSS 클래스를 추가하거나 제거하는 것입니다. 인라인 스타일을 직접 조작하는 것보다 CSS를 미리 작성해두고 클래스만 토글하는 방식이 관심사 분리와 유지보수성 측면에서 훨씬 우수합니다. classList는 이를 쉽게 만들어주는 API입니다.

// CSS:
// .active { color: blue; font-weight: bold; }
// .hidden { display: none; }
// .highlight { background: yellow; }

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

// add — 클래스 추가 (이미 있어도 중복 추가 안 됨)
el.classList.add("active");
el.classList.add("highlight", "special");  // 여러 개 동시에

// remove — 클래스 제거 (없어도 오류 없음)
el.classList.remove("active");
el.classList.remove("highlight", "special");  // 여러 개 동시에

// toggle — 있으면 제거, 없으면 추가
el.classList.toggle("active");  // 없으면 추가
el.classList.toggle("active");  // 있으면 제거

// toggle의 두 번째 인수 — 조건에 따라 강제 설정
const isLoggedIn = true;
el.classList.toggle("logged-in", isLoggedIn);  // true면 추가, false면 제거

// contains — 포함 여부 확인
console.log(el.classList.contains("active"));  // true/false

// replace — 클래스 교체
el.classList.replace("old-class", "new-class");

// 실전: 탭 UI
const tabs = document.querySelectorAll(".tab");
const panels = document.querySelectorAll(".panel");

tabs.forEach((tab, index) => {
  tab.addEventListener("click", () => {
    // 모든 탭·패널에서 active 제거
    tabs.forEach(t => t.classList.remove("active"));
    panels.forEach(p => p.classList.remove("active"));

    // 클릭된 탭·패널에 active 추가
    tab.classList.add("active");
    panels[index].classList.add("active");
  });
});

classList.toggle의 두 번째 인수는 강력한 기능입니다. 불리언 값을 받아 true면 클래스를 추가하고 false면 제거합니다. 조건에 따라 클래스를 관리할 때 if/else 대신 한 줄로 처리할 수 있습니다. 탭 UI 예시에서 보듯이 이벤트 처리와 결합하면 완전히 동작하는 인터랙티브 컴포넌트를 만들 수 있습니다. 이벤트 처리는 18강에서 자세히 배웁니다.

🖌️ style 속성 — 인라인 스타일

이 섹션에서는 style 속성으로 자바스크립트에서 직접 CSS 스타일을 적용하는 방법을 살펴보겠습니다.

클래스로 스타일을 관리하는 것이 원칙이지만, 동적으로 계산된 값(애니메이션 위치, 사용자 설정 색상 등)은 인라인 스타일이 필요합니다. style 속성을 통해 CSS 속성을 직접 설정할 수 있습니다.

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

// CSS 속성명은 camelCase로 변환
box.style.color = "red";                   // color
box.style.backgroundColor = "lightblue";   // background-color
box.style.fontSize = "20px";               // font-size
box.style.marginTop = "16px";              // margin-top
box.style.transform = "translateX(100px)"; // transform

// 현재 계산된 스타일 읽기 (클래스에서 온 값 포함)
const computed = getComputedStyle(box);
console.log(computed.color);      // "rgb(255, 0, 0)"
console.log(computed.fontSize);   // "20px"

// CSS 변수(Custom Property)와 연동 — 권장 패턴
// CSS에서: :root { --primary-color: #3b82f6; }
document.documentElement.style.setProperty("--primary-color", "#ef4444");
// 이 방법으로 사이트 전체 테마를 한 번에 변경

// 실전: 드래그 이동
const draggable = document.querySelector(".draggable");
draggable.addEventListener("mousemove", (e) => {
  draggable.style.left = e.pageX + "px";  // 단위 필수!
  draggable.style.top  = e.pageY + "px";
});

// 인라인 스타일 제거
box.style.color = "";  // 빈 문자열로 설정하면 인라인 스타일 제거됨

자바스크립트의 style 속성명은 CSS와 달리 camelCase를 사용합니다. background-color → backgroundColor, font-size → fontSize처럼 하이픈을 제거하고 다음 단어 첫 글자를 대문자로 씁니다. 스타일 값은 항상 문자열이며 단위도 함께 써야 합니다("20px", "100%"). getComputedStyle()은 인라인 스타일뿐 아니라 CSS 파일에서 적용된 값까지 포함한 최종 계산값을 읽습니다. CSS 변수와 연동하는 패턴은 다크 모드, 테마 변경처럼 전역 스타일을 동적으로 바꿀 때 특히 유용합니다.

🏷️ HTML 속성 조작

이 섹션에서는 src, href, data-* 같은 HTML 속성을 읽고 쓰는 방법을 살펴보겠습니다.

클래스나 스타일 외에도 src, href, disabled, 커스텀 data-* 속성처럼 HTML 요소의 속성을 동적으로 변경해야 할 때가 많습니다.

const img = document.querySelector("img");
const link = document.querySelector("a");
const btn = document.querySelector("button");

// getAttribute / setAttribute — 표준 속성
console.log(img.getAttribute("src"));     // 현재 src 값
img.setAttribute("src", "/new-image.jpg"); // src 변경
img.setAttribute("alt", "새 이미지 설명");

// DOM 속성으로 직접 접근 (표준 속성은 이 방법 선호)
link.href = "https://example.com";   // href 변경
btn.disabled = true;                 // 버튼 비활성화
btn.disabled = false;                // 버튼 활성화

// removeAttribute — 속성 제거
img.removeAttribute("alt");

// hasAttribute — 속성 존재 여부
console.log(btn.hasAttribute("disabled"));  // true/false

// data-* 속성 — dataset으로 접근
// <li data-id="42" data-category="fruit">사과</li>
const li = document.querySelector("li");
console.log(li.dataset.id);         // "42"
console.log(li.dataset.category);   // "fruit"
li.dataset.selected = "true";       // 새 data-* 속성 추가
console.log(li.getAttribute("data-selected"));  // "true"

// 실전: 이미지 지연 로딩
const images = document.querySelectorAll("img[data-src]");
images.forEach(img => {
  img.setAttribute("src", img.getAttribute("data-src"));
  img.removeAttribute("data-src");
});

표준 HTML 속성(src, href, id, disabled 등)은 DOM 프로퍼티로 직접 접근하는 것이 간결하고 빠릅니다. 커스텀 속성이나 비표준 속성에는 getAttribute/setAttribute를 사용합니다. data-* 속성은 HTML 요소에 커스텀 데이터를 저장하는 표준 방법입니다. dataset을 통해 접근할 때 data-user-name은 dataset.userName처럼 camelCase로 변환됩니다. 이 속성들은 자바스크립트로 요소를 식별하거나 추가 정보를 저장할 때 매우 유용합니다.

💡 종합 예제 — 다크 모드 토글

이 섹션에서는 지금까지 배운 classList, style, setAttribute를 종합해 다크 모드 토글 기능을 구현해 보겠습니다.

배운 내용을 모두 조합해 실용적인 기능을 만들어 봅시다. 버튼 클릭 시 페이지 전체의 다크 모드를 토글하는 기능입니다.

// CSS:
// body.dark { background: #1a1a2e; color: #e0e0e0; }
// .toggle-btn { cursor: pointer; }

const body = document.body;
const toggleBtn = document.querySelector(".toggle-btn");
const icon = document.querySelector(".toggle-icon");

// 저장된 설정 불러오기 (27강에서 자세히)
const savedTheme = localStorage.getItem("theme");
if (savedTheme === "dark") {
  body.classList.add("dark");
}

toggleBtn.addEventListener("click", () => {
  const isDark = body.classList.toggle("dark");

  // 아이콘 변경
  icon.textContent = isDark ? "🌙" : "☀️";

  // 버튼 속성 업데이트 (접근성)
  toggleBtn.setAttribute("aria-label", isDark ? "라이트 모드로 전환" : "다크 모드로 전환");

  // 테마 저장
  localStorage.setItem("theme", isDark ? "dark" : "light");
});

📝 핵심 요약

17강에서 배운 내용을 정리해 보겠습니다.

API사용법주의점
textContent순수 텍스트 읽기/쓰기HTML 태그 무시, XSS 안전
innerHTMLHTML 마크업 읽기/쓰기사용자 입력 직접 삽입 금지!
classList.add/remove클래스 추가/제거여러 클래스 동시 가능
classList.toggle클래스 토글2번째 인수로 조건 설정 가능
style.property인라인 스타일 적용camelCase, 단위 필수
setAttribute/getAttributeHTML 속성 읽기/쓰기커스텀 속성에 사용
datasetdata-* 속성 접근kebab-case → camelCase

다음 강인 18강 — 이벤트 처리에서는 사용자와 상호작용하는 핵심 메커니즘을 배웁니다. 클릭, 입력, 마우스 이동, 키보드 누름 등 다양한 사용자 행동에 반응하는 이벤트 리스너를 작성하는 방법을 배우면, 지금까지 배운 DOM 조작을 사용자 행동과 연결해 진짜 인터랙티브 웹 페이지를 완성할 수 있습니다!

관련 주제

  • textContent innerHTML
  • classList add remove toggle
  • 인라인 스타일
  • setAttribute getAttribute
  • 개발·프로그래밍
  • 개발·프로그래밍 강의
  • 자바스크립트 기초 30강 — 웹을 움직이는 언어
  • 무료강의
  • 무료 온라인 강의
  • NUGUNA
  • 누구나

📚 시리즈 전체 공유

자바스크립트 기초 30강 — 웹을 움직이는 언어

이 강의가 속한 시리즈는 총 22강, 모두 무료입니다. 처음부터 배우려는 동료에게 시리즈 전체를 알려 주세요.

댓글

0/1000

불러오는 중...