JavaScript / getAttribute()로 HTML 속성 값 가져오기

element.getAttribute("속성명")은 요소에 지정된 HTML 속성의 값을 문자열로 읽으며, 해당 속성이 없으면 null을 반환합니다. 체크박스의 현재 선택 상태나 입력란의 현재 값처럼 사용자의 조작으로 달라지는 상태는 속성값과 다를 수 있으므로, checked나 value 같은 DOM 프로퍼티를 구분해 사용하세요.

문법과 반환값 확인하기

const link = document.getElementById("guide");

if (link !== null) {
  const href = link.getAttribute("href");
  console.log(href);
}

메서드 앞에는 실제 요소 객체가 와야 합니다. document에서 직접 getAttribute()를 호출하는 방식은 아닙니다. 또한 getElementById()가 요소를 찾지 못해 null을 반환한 경우에는 먼저 선택 경로와 실행 시점을 고쳐야 합니다. 요소가 없는 경우와 요소에 특정 속성이 없는 경우는 서로 다른 문제입니다.

HTML의 attribute는 마크업에 기록되는 ‘속성’이고, DOM property는 JavaScript 객체에서 접근하는 ‘프로퍼티’입니다. 서로 대응하는 항목도 있지만 항상 같은 표현이나 같은 상태를 뜻하지는 않습니다. MDN의 getAttribute() 문서는 반환값을 문자열 또는 null로 정의합니다.

상황 반환값 판단 방법
title="안내" "안내" 문자열을 필요한 용도로 사용
title="" 빈 문자열 "" 속성은 있으나 값이 비어 있음
title 속성이 없음 null value === null로 구분
data-count="3" 문자열 "3" 계산 전 숫자 변환·검사 필요

빈 문자열과 없는 속성을 구분하기

const title = element.getAttribute("title");

if (title === null) {
  console.log("title 속성이 없습니다.");
} else if (title === "") {
  console.log("title 속성의 값이 비었습니다.");
} else {
  console.log(title);
}

이 부분 코드는 이미 선택한 요소가 element에 있다는 전제입니다. 단순히 if (title)만 쓰면 null과 빈 문자열이 모두 거짓으로 취급되므로 두 경우를 구분하지 못합니다. 값이 무엇인지와 관계없이 속성의 존재만 확인하려면 element.hasAttribute("title")이 의도를 더 분명하게 표현합니다.

data-*의 값도 숫자나 불리언으로 자동 변환되지 않습니다. 예를 들어 data-count="3"을 읽은 값에 1을 더하면 문자열 연결이 일어날 수 있습니다. 먼저 값의 존재와 빈 문자열을 검사한 뒤 Number()로 변환하고 유한한 수인지 확인하세요. data-user-id는 element.dataset.userId로도 읽을 수 있지만 이 값 역시 문자열입니다. MDN의 dataset 설명에서 이름 변환 규칙을 확인할 수 있습니다.

href와 checked를 비교하는 전체 예제

아래 코드를 get-attribute.html로 저장한 뒤 브라우저에서 여세요. 링크의 href는 같은 문서의 실제 제목을 가리키며, 체크박스는 처음부터 선택된 상태입니다. 스크립트는 요소 뒤에 배치되어 별도 로딩 대기 코드 없이 실행됩니다.

<!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>HTML 속성과 현재 상태 읽기</title>
</head>
<body>
<h1>속성 읽기</h1>
<p><a id="guide" href="#details" title="" data-count="3">설명으로 이동</a></p>
<label><input id="agree" type="checkbox" checked> 안내 확인</label>
<pre id="output"></pre>
<h2 id="details">설명</h2>
<p>체크를 해제했다가 다시 체크하면서 출력값을 비교하세요.</p>
<script>
const guide = document.getElementById("guide");
const agree = document.getElementById("agree");
const output = document.getElementById("output");
function render() {
  output.textContent = [
    `href 속성: ${guide.getAttribute("href")}`,
    `href 프로퍼티: ${guide.href}`,
    `title: ${JSON.stringify(guide.getAttribute("title"))}`,
    `없는 aria-label: ${JSON.stringify(guide.getAttribute("aria-label"))}`,
    `data-count의 자료형: ${typeof guide.getAttribute("data-count")}`,
    `checked 속성: ${JSON.stringify(agree.getAttribute("checked"))}`,
    `현재 checked: ${agree.checked}`
  ].join("\n");
}
agree.addEventListener("change", render);
render();
</script>
</body>
</html>

처음에는 href 속성: #details, title: "", 없는 aria-label: null이 표시됩니다. data-count를 읽은 값의 자료형은 string입니다. guide.href는 문서의 기준 URL을 사용해 해석된 주소를 제공하므로, 로컬 파일을 열었는지 웹 서버에서 열었는지에 따라 실제 출력 주소가 달라집니다. URL을 원래 지정한 상대 표현으로 읽고 싶은지, 해석된 주소로 읽고 싶은지에 따라 선택하세요.

체크를 해제하면 현재 checked는 false로 바뀌지만, getAttribute("checked")는 계속 빈 문자열입니다. 마크업에 빈 checked 속성이 존재한다는 사실과 현재 사용자의 선택 상태가 다르기 때문입니다. 다시 체크하면 현재 상태가 true로 돌아오며, 새로고침하면 이 예제의 처음 상태를 다시 비교할 수 있습니다. MDN의 checked 프로퍼티 설명은 기본 선택 상태와 현재 선택 상태를 구분합니다.

실습에서는 체크박스만 조작해 차이를 관찰하세요. HTML의 title=""을 잠깐 제거하면 빈 문자열이 null로 바뀌는 것도 확인할 수 있습니다. 비교 후에는 속성을 다시 추가해 원래 예제로 되돌립니다. 출력이 없으면 파일 저장 여부와 Console의 요소 선택 오류를 먼저 확인하세요.

속성에서 읽은 문자열도 안전하게 표시하기

getAttribute()는 HTML의 문자 참조를 원본 그대로 보관하는 함수가 아닙니다. 예를 들어 마크업에 data-label="&lt;b&gt;예시&lt;/b&gt;"라고 적으면 HTML 파싱을 거친 값에는 실제 <b>예시</b> 문자열이 들어갑니다. 외부에서 받은 값을 속성에 저장했다가 다시 읽었다는 이유만으로 안전한 HTML이라고 판단하면 안 됩니다.

const label = element.getAttribute("data-label");
output.textContent = label ?? "";

위 코드는 이미 선택한 출력 요소 output에 문자열을 글자로 표시합니다. innerHTML로 옮기면 태그로 해석되는 점이 다릅니다. 속성값을 바꿀 때는 setAttribute(), 제거할 때는 removeAttribute()를 사용하되, 현재 폼 상태를 다루는 작업에서는 해당 DOM 프로퍼티가 더 적합한지도 함께 판단하세요.