이전까지는 HTML 태그의 속성을 다룰 때, 대부분 표준 속성들을 사용했을 겁니다.
하지만 자바스크립트로 HTML 태그를 다루다 보면 때로는 표준이 아닌 속성을 사용하게 될 때도 있는데요.
아래 코드를 한 번 살펴봅시다.
<body>
<p>할 일 : <b field="title"></b></p>
<p>담당자 : <b field="manager"></b></p>
<p>상태 : <b field="status"></b></p>
<div>
상태 변경:
<button class="btn" status="대기중">대기중</button>
<button class="btn" status="진행중">진행중</button>
<button class="btn" status="완료">완료</button>
</div>
<script src="index.js"></script>
</body>
</html>
[status] {
padding: 5px 10px;
}
[status="대기중"] {
background-color: #FF6767;
color: #FFFFFF;
}
[status="진행중"] {
background-color: #5f62ff;
color: #FFFFFF;
}
[status="완료"] {
background-color: #07c456;
color: #FFFFFF;
}
위 코드를 보시면 b
태그들의 field
속성과 button
태그들의 status
라는 속성이 보이는데요. 이 두 속성은 해당 태그의 표준 속성이 아닙니다.
그리고 혹시, 위 코드의 css 부분에서 대괄호('[')를 이용한 css 선택자를 처음 보시는 분들도 있을 것 같은데요. [속성이름]
처럼 대괄호를 이용하면 대괄호 안에 있는 속성이름을 가진 태그들을 선택할 수 있고 [속성이름="값"]
처럼 작성하면, 좀 더 구체적으로 속성이름에 해당 값을 가진 태그들을 선택할 수도 있습니다.
아무튼, 이런 상황에서 비표준 속성은 어떤 식으로 다룰 수 있는지 한 번 살펴봅시다.
가장 간단하게는 아래와 같이 querySelector로 태그를 선택할 때 css 선택자를 활용해서 태그를 선택하는 데에 활용할 수도 있습니다.
const fields = document.querySelectorAll('[field]');
console.log(fields);
비표준 속성은 객체 형태의 데이터가 있을 때, 각 프로퍼티 값들이 들어갈 태그를 구분하는데 활용할 수도 있습니다.
const fields = document.querySelectorAll('[field]');
const task = {
title: '코드 에디터 개발',
manager: 'CastleRing, Raccoon Lee',
status: '',
};
for (let tag of fields) {
const field = tag.getAttribute('field');
tag.textContent = task[field];
}
getAttribute
메소드를 활용해서 속성값을 가져오고, setAttribute
메소드를 활용해서 속성값을 설정해주는 원리로 이벤트를 통해 실시간으로 스타일을 변경하거나 데이터를 변경하는데 활용할 수 있습니다.
때로는 class
를 다루는 것보다 setAttribute
로 비표준 속성을 변경하는게 스타일을 다루기에 오히려 편리한 경우도 있습니다.
const fields = document.querySelectorAll('[field]');
const task = {
title: '코드 에디터 개발',
manager: 'CastleRing, Raccoon Lee',
status: '',
};
for (let tag of fields) {
const field = tag.getAttribute('field');
tag.textContent = task[field];
}
const btns = document.querySelectorAll('.btn');
for (let btn of btns) {
const status = btn.getAttribute('status');
btn.onclick = function () {
fields[2].textContent = status;
fields[2].setAttribute('status', status);
};
}
다양한 방식으로 활용되는 비표준 속성에는 한 가지 문제가 있습니다.
비표준 속성을 사용해 코드를 작성했을 때 시간이 지나서 나중에 그 속성이 표준으로 등록되면 문제가 발생할 수 있다는 건데요.
HTML은 아직까지도 개발자들의 요구를 반영하기 위해 계속해서 발전하는 언어입니다. 그래서 이런 경우 예기치 못한 부작용이 발생할 수 있는 것이죠.
예를 들어서, 만약 glitter
라는 비표준 속성을 만들어서 glitter
속성값이 true
면 마우스를 올렸을 때 주변에 별이 반짝이는 애니메이션이 동작하도록 프로그램를 설계했다고 가정해봅시다.
그런데 갑자기 glitter
라는 속성이 true
일 때 태그가 계속 깜빡거리는 기능을 하는 표준으로 생겨나버리면 우리가 처음에 설계한 방식대로 동작하지 않을 수 있겠죠?
그래서 비표준 속성을 사용하기 위해 미리 약속된 방식이 존재하는데요. 바로 data-*
속성입니다.
data-
로 시작하는 속성은 모두 dataset
이라는 프로퍼티에 저장되는데요. 예를 들어서 data-status
라는 속성이 있다면, element.dataset.status
라는 프로퍼티에 접근해서 그 값을 가져올 수 있는 것이죠.
그래서 본문의 코드도 아래와 같이 고치고,
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>JS with Codeit</title>
</head>
<body>
<p>할 일 : <b data-field="title"></b></p>
<p>담당자 : <b data-field="manager"></b></p>
<p>상태 : <b data-field="status"></b></p>
<div>
상태 변경:
<button class="btn" data-status="대기중">대기중</button>
<button class="btn" data-status="진행중">진행중</button>
<button class="btn" data-status="완료">완료</button>
</div>
<script src="index.js"></script>
</body>
</html>
[data-status] {
padding: 5px 10px;
}
[data-status="대기중"] {
background-color: #FF6767;
color: #FFFFFF;
}
[data-status="진행중"] {
background-color: #5f62ff;
color: #FFFFFF;
}
[data-status="완료"] {
background-color: #07c456;
color: #FFFFFF;
}
자바스크립트 코드도 다음과 같이 고쳐주면,
const fields = document.querySelectorAll('[data-field]');
const task = {
title: '코드 에디터 개발',
manager: 'CastleRing, Raccoon Lee',
status: '',
};
for (let tag of fields) {
const field = tag.dataset.field;
tag.textContent = task[field];
}
const btns = document.querySelectorAll('.btn');
for (let btn of btns) {
const status = btn.dataset.status;
btn.onclick = function () {
fields[2].textContent = status;
fields[2].dataset.status = status;
};
}
조금 더 안전하게 비표준 속성을 활용할 수 있습니다.
아래 코드를 실행해서 상태변경 버튼을 클릭해 보세요! :)
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>JS with Codeit</title>
</head>
<body>
<p>할 일 : <b data-field="title"></b></p>
<p>담당자 : <b data-field="manager"></b></p>
<p>상태 : <b data-field="status"></b></p>
<div>
상태 변경:
<button class="btn" data-status="대기중">대기중</button>
<button class="btn" data-status="진행중">진행중</button>
<button class="btn" data-status="완료">완료</button>
</div>
<script>
const fields = document.querySelectorAll('[data-field]');
const task = {
title: '코드 에디터 개발',
manager: 'CastleRing, Raccoon Lee',
status: '',
};
for (let tag of fields) {
const field = tag.dataset.field;
tag.textContent = task[field];
}
const btns = document.querySelectorAll('.btn');
for (let btn of btns) {
const status = btn.dataset.status;
btn.onclick = function () {
fields[2].textContent = status;
fields[2].dataset.status = status;
};
}
</script>
</body>
</html>
[data-status] {
padding: 5px 10px;
}
[data-status="대기중"] {
background-color: #FF6767;
color: #FFFFFF;
}
[data-status="진행중"] {
background-color: #5f62ff;
color: #FFFFFF;
}
[data-status="완료"] {
background-color: #07c456;
color: #FFFFFF;
}
사실 비표준 속성을 활용하는 것은 개발자의 선택적인 부분입니다. 반드시 비표준 속성을 활용해야만 하는 상황은 아마 없을지도 모릅니다.
하지만 상황에 따라서 비표준 속성이 필요할 수도 있고 혹은 비표준 속성을 활용하는 것이 조금 더 효율적일 수도 있으니 다양한 상황들을 고려해서, 만약 비표준 속성을 활용해야 한다면 data-*
형태와 dataset
프로퍼티를 사용하는 것이 조금 더 안전하다
는 점도 꼭 잊지 말고 기억해두시면 좋을 것 같습니다.