포스트

[Vanilla JS] DOM 요소 읽기: 텍스트·속성·스타일·상태를 가져오는 방법

[Vanilla JS] DOM 요소 읽기: 텍스트·속성·스타일·상태를 가져오는 방법

DOM 요소 읽기는 화면에 있는 정보를 자바스크립트 로직으로 가져오는 단계이며,
유효성 검사, 조건 분기, 렌더링 동기화, 사용자 입력 처리의 기반이 된다.
본 글에서는 바닐라 JavaScript 환경에서 DOM 요소로부터 값을 “읽는” 대표 방법을 정리한다.



1. 텍스트 읽기: textContent, innerText, innerHTML

textContent

요소 내부의 텍스트를 그대로 가져온다. 줄바꿈과 공백을 포함하며, 화면 표시 여부와 무관하게 텍스트를 읽는다.

1
2
3
<h1 class="title">
  안녕하세요 <span style="display:none">숨김</span>
</h1>
1
2
const el = document.querySelector(".title");
console.log(el?.textContent); // "안녕하세요 숨김" (숨김 여부와 무관)
  • 장점: 빠르고 예측 가능하다.
  • 권장: 텍스트가 필요하다면 기본 선택으로 삼기 좋다.


innerText

요소 내부의 텍스트를 사용자에게 보이는 형태를 기준으로 가져온다.
CSS에 의해 숨김 처리된 텍스트는 제외될 수 있고, 레이아웃 계산이 관여해 textContent보다 비용이 커질 수 있다.

1
2
3
<h1 class="title">
  안녕하세요 <span style="display:none">숨김</span>
</h1>
1
2
const el = document.querySelector(".title");
console.log(el?.innerText); // "안녕하세요" (보이는 텍스트 기준)

화면에 보이는 텍스트 기준이 필요할 때 사용한다.


innerHTML

요소 내부의 HTML 문자열을 가져온다.

1
2
3
<div class="content">
  <strong>강조</strong> 텍스트
</div>
1
2
const el = document.querySelector(".content");
console.log(el?.innerHTML); // "<strong>강조</strong> 텍스트"

마크업 구조 자체가 필요할 때만 제한적으로 사용한다.

읽기 자체는 문제 없으나, 이 값을 다시 조합해 DOM에 넣는 흐름에서는 XSS 위험이 생길 수 있다.

정리하자면, 대부분의 읽기 상황에서는 textContent가 가장 안전하고 일관된 선택이다.




2. 속성 읽기: getAttribute와 프로퍼티 접근

DOM 요소는 HTML 속성(attribute)DOM 프로퍼티(property)를 모두 가진다.
읽기 목적에 따라 적절한 방식을 선택해야 한다.

getAttribute(name)

HTML에 작성된 속성 값을 문자열로 가져온다.

1
<img class="avatar" src="/img/cat.png" alt="고양이 아바타" />
1
2
3
const img = document.querySelector(".avatar");
console.log(img?.getAttribute("alt")); // "고양이 아바타"
console.log(img?.getAttribute("src")); // "/img/cat.png"

반환값 : 문자열 또는 null


프로퍼티로 읽기: element.id, element.value 등

DOM 요소는 자바스크립트에서 사용하기 편한 프로퍼티를 제공한다.

1
<input id="email" type="email" value="test@example.com" />
1
2
3
const input = document.querySelector("#email");
console.log(input?.id);    // "email"
console.log(input?.value); // "test@example.com" (현재 값)

현재 상태를 읽는 데 유리하다(특히 입력값).


data-* 읽기: dataset

기능 제어용으로 data-* 속성을 사용하는 경우가 많다.

1
2
3
4
5
6
<ul class="todo-list">
  <li class="todo-item" data-id="42" data-status="done">
    <button class="btn" data-action="toggle">완료 토글</button>
    <button class="btn" data-action="remove">삭제</button>
  </li>
</ul>
1
2
3
4
5
6
7
8
const item = document.querySelector(".todo-item");
if (!item) return;

console.log(item.dataset.id);     // "42"
console.log(item.dataset.status); // "done"

const btn = item.querySelector('[data-action="toggle"]');
console.log(btn?.dataset.action); // "toggle"
  • 반환값은 기본적으로 문자열이다.
  • 숫자가 필요하면 변환이 필요하다.
1
const idNum = Number(item?.dataset.id);


3. 폼 입력값 읽기: value, checked, selectedIndex

폼 요소는 “읽기”의 비중이 매우 높다. 특히 value는 가장 많이 등장한다.

input, textarea 읽기 : value

1
2
<input id="nickname" type="text" value="test" />
<textarea id="bio">소개 글</textarea>
1
2
3
4
5
const nickname = document.querySelector("#nickname");
const bio = document.querySelector("#bio");

console.log(nickname?.value); // "test"
console.log(bio?.value);      // "소개 글"


체크박스/라디오 상태 읽기 : checked

1
2
3
4
5
6
7
8
9
10
11
<label>
  <input id="agree" type="checkbox" checked />
  약관 동의
</label>

<label>
  <input name="gender" type="radio" value="M" checked /></label>
<label>
  <input name="gender" type="radio" value="F" /></label>
1
2
3
4
5
const agree = document.querySelector("#agree");
console.log(agree?.checked); // true

const gender = document.querySelector('input[name="gender"]:checked');
console.log(gender?.value);  // "M"


select 값 읽기

1
2
3
4
<select id="city">
  <option value="seoul">서울</option>
  <option value="incheon" selected>인천</option>
</select>
1
2
3
4
const sel = document.querySelector("#city");

console.log(sel?.value);        // "incheon"
console.log(sel?.selectedIndex); // 1


4. 클래스/상태 읽기: classList, matches, closest

특정 클래스 보유 여부: classList.contains

1
<button class="btn active">저장</button>
1
2
const btn = document.querySelector(".btn");
console.log(btn?.classList.contains("active")); // true


선택자 일치 여부: matches

1
2
3
4
<nav class="menu">
  <a class="item" href="#"></a>
  <a class="item" href="#">소개</a>
</nav>
1
2
3
4
5
6
7
8
document.addEventListener("click", (e) => {
  const t = e.target;
  if (!(t instanceof Element)) return;

  if (t.matches(".menu .item")) {
    console.log("메뉴 아이템 클릭");
  }
});


가장 가까운 조상 탐색: closest

1
2
3
4
5
<div class="card" data-id="7">
  <div class="content">
    <button class="like">좋아요</button>
  </div>
</div>
1
2
3
4
5
6
7
8
9
document.addEventListener("click", (e) => {
  const t = e.target;
  if (!(t instanceof Element)) return;

  if (!t.matches(".like")) return;

  const card = t.closest(".card");
  console.log(card?.dataset.id); // "7"
});


5. 스타일/크기 읽기: getComputedStyle, getBoundingClientRect

실제 적용된 CSS 읽기: getComputedStyle

1
2
3
4
5
<div class="box">BOX</div>

<style>
  .box { width: 120px; padding: 10px; border: 1px solid #ddd; }
</style>
1
2
3
4
5
6
const el = document.querySelector(".box");
if (el) {
  const style = getComputedStyle(el);
  console.log(style.width);   // "120px"
  console.log(style.padding); // "10px"
}


위치/크기 읽기: getBoundingClientRect

1
2
3
4
5
<div class="banner">BANNER</div>

<style>
  .banner { margin-top: 40px; height: 60px; }
</style>
1
2
3
4
5
const el = document.querySelector(".banner");
if (el) {
  const rect = el.getBoundingClientRect();
  console.log(rect.top, rect.left, rect.width, rect.height);
}


6. DOM 구조 읽기: 부모/자식/형제 탐색

1
2
3
4
5
<ul class="list">
  <li class="item">A</li>
  <li class="item current">B</li>
  <li class="item">C</li>
</ul>
1
2
3
4
5
6
const current = document.querySelector(".item.current");
if (!current) return;

console.log(current.parentElement?.className);           // "list"
console.log(current.previousElementSibling?.textContent); // "A"
console.log(current.nextElementSibling?.textContent);     // "C"


7. 실전에서 자주 쓰는 “읽기” 패턴

존재 여부를 먼저 확인한다

1
<h2 class="toast" hidden>저장되었습니다.</h2>
1
2
3
4
const toast = document.querySelector(".toast");
if (!toast) return;

console.log(toast.hasAttribute("hidden")); // true

문자열을 전제로 두고 타입 변환을 명시한다.

1
<p id="price">12000</p>
1
2
3
4
const priceText = document.querySelector("#price")?.textContent ?? "0";
const price = Number(priceText);

console.log(price + 1000); // 13000


마무리

DOM 요소 읽기는

  • 텍스트(textContent)
  • 속성(getAttribute/dataset)
  • 입력값(value/checked)
  • 상태(classList)
  • 스타일(getComputedStyle)

무엇을 읽는지에 따라 API가 달라지며,
예시 HTML 구조를 함께 두고 null과 문자열 타입을 기본 전제로 안전하게 처리하는 것이 중요하다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.