...
HTML 데이터셋 속성
HTML의 데이터셋 속성은 커스텀 사용자 속성을 DOM 요소에 저장하는데 표준화된 방법을 제공한다. 한마디로 자바스크립트에서 변수를 사용하듯이, 일종의 html의 변수 역할이라고 말할 수 있다.
데이터셋 속성의 장점
일반 속성 과 데이터셋 속성
데이터셋도 일종의 속성(attribute)이다. 보통 html에서 속성이라 하는 것은 여러분도 잘 알듯이 id, class, src, title 등의 태그에 붙이는 어트리뷰트를 말한다. 이들 속성은 특정 태그의 소스 경로나 이름, 너비, 아이디를 기재하는데 정해져 있다.
그런데 html 태그에 그 엘리먼트만이 지니고 있는 고유한 커스텀 값을 지정해 사용하고 싶을 때가 있다. 마치 아래 코드 처럼 input 태그의 value 속성으로 값을 기재해주면, 자바스크립트로 별도로 변수를 만들어 이 변수는 어느 엘리먼트의 값을 표현한다는 매칭 시키는 작업을 줄일 수 있어 직관성과 생산성이 향상 되기 때문이다.
<input type="radio" name="gender" value="male">
<input type="radio" name="gender" value="female">
실제로 데이터 속성이 나오기 이전에는, 만일 html 상에 어떠한 고유한 값을 저장할 필요가 있다면 다음과 같이 hidden 으로 태그를 문서로부터 감추고 value 속성으로 값을 저장하는 용도로써 쓰이기도 하였다.
<!-- hidden 타입으로 태그를 문서에서 가리고,
Country라는 이름으로 Norway 값을 문서에 저장하고 꺼내 쓸때 자주 애용되었던 방식이다 -->
<input type="hidden" name="Country" value="Norway"> <!-- let Contry = "Norway" -->
하지만 value 속성은 아무 엘리먼트에서 사용할 수 있는 속성이 아니다. (사용은 가능하지만 HTML 표준에 위배된다)
그래서 만일 input 태그 외에 시맨틱 태그나 div 태그에도 별도의 태그의 고유 값을 저장하고 싶을때는 자바스크립트로 복잡하게 우회하여야 했다.
그러나 데이터셋은 태그 내에 data- 로 시작하는 키워드를 기재하고 그 뒤에 하이픈(-)이 조합된 형태로 개발자가 정의하고 싶은 속성명을 기재해주고 속성값을 써주면 사용자 변수가 완성된다.
<input type="text" data-country="Norway" data-code="c03" name="Country">
데이터 속성을 쓰면 훨씬 스크립트가 간결해지며 또한 하나의 요소에는 여러 데이터 속성을 동시에 사용할 수도 있어 확장성이 높다.
데이터셋 사용 사례
앞서 말했듯 데이터셋을 이용해도 되고 안해도 된다. 다만 아래와 같이 '좋아요 갯수 버튼'을 표시하는 요소를 만들 경우, 이 좋아요 갯수를 자바스크립트로 가지고 있는 것보다 이렇게 직접 버튼 요소에 갯수값을 인라인으로 직접 표현함으로써 보다 직관적이게 된다.
<button data-id="341">좋아요♡</button>
데이터셋에 배열, 객체 데이터 저장
좀 더 기능을 응용하여, 데이터 속성에는 단순 문자열을 넘어 객체와 배열도 저장이 가능하다. 정확히 말하자면 원래는 문자열만 저장이 가능하지만, 객체 형태로 된 문자열과 배열 형태로 된 문자열을 노드에 지정하고 이를 자바스크립트로 별도의 파싱 작업을 통해 사용함으로써, 마치 html 엘리먼트에 인라인으로 객체 데이터를 기재할 수 있다는 응용 방법이 있다고 보면 된다. (자바스크립트로 파싱하는 방법은 바로 뒤에서 다룬다)
<!-- 객체 형태로 된 문자열 데이터셋 -->
<div data-person='{"name": "Chris Coyier", "job": "Web Person"}'></div>
<!-- 배열 형태로 된 문자열 데이터셋 -->
<div data-fruit='["apple", "banana", "melon"]'></div>
자바스크립트로 데이터셋 다루기
JavaScript 데이터셋 사용법
데이터셋 접근하기
html에 다음과 같은 데이터셋 속성을 가진 div 엘리먼트가 있다고 하자.
<div id="post" data-columns="3" data-title="javascript" data-index-number="123">
...
</div >
자바스크립트로 이 요소의 데이터 속성에 접근하여 값을 읽어들일 수 있고 재변경도 가능하다. 자바스크립트로 데이터 속성에 접근하는 대표적인 방법은 다음 두가지가 있다.
dataset프로퍼티로 접근- 일반적인 속성 접근 메서드
getAttribute()사용
const $div = document.getElementById('post');
// 일반적인 객체 속성 접근
$div.dataset.columns // "3"
// 배열 인덱스로 접근
$div.dataset['title'] // "javascript"
// data-index-number에서 dataset.indexNumber로 변환
$div.dataset.indexNumber // "12314"
const $div = document.getElementById('post');
$div.getAttribute('data-columns') // "3"
$div.getAttribute('data-title') // "javascript"
$div.getAttribute('data-index-number') // "12314"
둘중 어느 방법으로 접근하든 편한 방식으로 사용하면 된다. 다만 만일 IE 와 같은 데이터셋 미지원 브라우저에서는 getAttribute()를 사용해야 한다.
이때 dataset 프로퍼티로 접근할 경우 속성 이름이 자동으로 낙타 표기법(Camel-Case) 으로 변환된다는 점은 유의해야 한다. 자바스크립트에서 변수명으로 - 기호가 허용되지 않기 때문이다. 그래서 data-index-number 에서 dataset.indexNumber로 변환되게 된다.
데이터셋 추가 / 변경 하기
역시나 자바스크립트로 데이터 속성을 추가하거나 값을 변경하는 대표적인 방법은 다음 두가지가 있다.
- dataset 프로퍼티로 접근해 추가/변경
- 일반적인 속성 변경 메서드
setAttribute()사용
const $div = document.getElementById('post');
$div.dataset.comments = '10';
$div.dataset.countryLangInfo = 'ko';
// data-country-lang-info 로 저장
const $div = document.getElementById('post');
$div.setAttribute('data-comments', '10')
$div.setAttribute('data-country-lang-info', 'ko')
<div id="post"
data-columns="3"
data-title="javascript"
data-index-number="123"
data-comments="10"
data-country-lang-info="ko"
>
...
</div>
데이터셋 삭제 하기
자바스크립트로 데이터 속성을 제거하는 대표적인 방법은 다음 두가지가 있다.
delete키워드로 객체 속성 삭제- 일반적인 속성 제거 메서드
removeAttribute()사용
const $div = document.getElementById('post');
delete $div.dataset.title; // delete 키워드로 객체 속성 삭제
$div.removeAttribute('data-comments');
데이터셋 리스트 출력
자바스크립트는 DOM 생성 시점에 data- 로 시작하는 속성들을 하나로 모아 dataset 맵(Map)을 만들어 관리한다. 위처럼 데이터셋 속성을 하나씩 출력해 확인할 수도 있지만, .dataset 프로퍼티 자체를 접근하면 아래 처럼 데이터셋 관련 모든 속성 리스트 출력이 가능하다.
console.log($div.dataset)
특정 데이터셋을 가지는 노드 가져오기
querySelector로 특정한 데이터셋을 가지고 있는 요소를 가져오려면, 속성 선택자 문법과 혼합하여 사용하면 된다.
document.querySelector('div[data-title="javascript" ]');
document.querySelectorAll('div[data-comments="10"]');
JSON 데이터셋 다루기
포스팅 초반에 잠깐 소개한 데이터셋으로 배열, 객체 형태의 문자열을 저장하여 이를 나중에 자바스크립트로 파싱하여 사용한다고 말한 바 있다. 방법은 전혀 어렵지 않은데 자바스크립트의 JSON 객체의 메서드를 통해 간단하게 변환이 가능하다. 자바스크립트에선 배열과 객체 모두 Object로 취급되기 때문에 이런식으로 응용이 가능한 것이다.
JSON 데이터셋 읽기
<!-- 객체 형태로 된 문자열 데이터셋 -->
<div id='person' data-person='{"name": "Chris Coyier", "job": "Web Person"}'></div>
<!-- 배열 형태로 된 문자열 데이터셋 -->
<div id='fruit' data-fruit='["apple", "banana", "melon"]'></div>
/* 데이터셋 문자열 객체를 자바스크립트 객체로 변환 */
const $div1 = document.querySelector('#person');
const obj = $div1.dataset.person; // 데이터셋 가져오기
const people = JSON.parse(obj); // 자바스크립트 object로 변환
console.log(people.name); // Chris Coyier
console.log(people.job); // Web Person
/* 데이터셋 문자열 배열을 자바스크립트 배열로 변환 */
const $div2 = document.querySelector('#fruit');
const arr = $div2.dataset.fruit; // 데이터셋 가져오기
const fruits = JSON.parse(arr);
console.log(fruits); // ['apple', 'banana', 'melon']
JSON 데이터셋 쓰기
// html 노드에 추가하고 싶은 객체 데이터 (배열도 가능)
const info = {
id: "slider",
min: 3,
max: 50
};
// 자바스크립트 객체를 문자열로 변환
const str = JSON.stringify(info);
// 데이터셋에 쓰기
$div1.dataset.info = str;
// or
$div1.setAttribute('data-info', str);
<div id='person'
data-person='{"name": "Chris Coyier", "job": "Web Person"}'
data-info='{"id":"slider","min":3,"max":50}'
>
</div>
JQuery 데이터셋 사용법
제이쿼리에서는 좀 더 편한 데이터셋 전용 메소드 data() 를 제공한다.
데이터셋 저장
$('div').data(key) // 데이터 읽기
<span data-member-name='인파'>이름</span>
<script>
$("#span").data("memberName");
$("#span").attr("data-member-name"); // 일반 속성 메서드로도 가져올 수 있다
</script>
만일 key를 생략하고 .data()으로 호출할 경우에는 해당 엘리먼트에 저장된 모든 data들이 JSON형식으로 리턴된다.
데이터셋 추가 / 변경 하기
$('div').data(key, value) // 데이터 저장
데이터셋 삭제 하기
$('div').removeData(key)
데이터셋을 사용하는 라이브러리
이러한 데이터셋은 사용자가 특정 노드에 라이브러리의 효과를 적용하는데 있어 정말 간편하게 설정하도록 도와준다. 대표적인 라이브러리로 스크롤 움직임에 따라 개체에 움직임을 주는 애니메이션을 주는 AOS 라이브러리를 들 수 있는데, 사용법을 보면, 애니메이션 효과를 주고 싶은 태그에 data-aos 관련 데이터 속성을 기재하기만 하고 소스를 불러오면 알아서 적용이 되게 된다.
<html>
<head>
<!-- AOS 라이브러리 불러오기-->
<link rel="stylesheet" href="https://unpkg.com/aos@2.3.1/dist/aos.css">
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
</head>
<body>
<!-- data-aos-* 속성을 태그에다가 써주면 알아서 동작되게 된다 -->
<div data-aos="fade-up"
data-aos-offset="200"
data-aos-easing="ease-out-cubic"
data-aos-duration="2000"
>
</div>
<!-- AOS 스크립트 시작 -->
<script>
AOS.init(); // 자바스크립트로 init()을 해야 동작한다.
</script>
</body>
</html>
CSS로 데이터셋 다루기
데이터셋 역시 html 속성 중 하나이기 때문에 속성 선택자를 통해 CSS에서도 접근하여 스타일링을 지정할 수 있다.
<div class="card" data-foo="bar">content</div>
div.card[data-foo="bar"] {
color: red;
}
CSS 데이터셋 활용 사례
데이터셋 선택자로 클래스 지정자를 절약
이런식으로 데이터셋 속성으로 CSS 접근자로 이용하면 스크립트를 핸들링하기 위해서 의미 없는 class나 id 사용을 자게하게 되고, 클래스 지정자가 많이 사용된 경우 데이터셋 속성을 준 요소만 별도로 스타일 요소를 적용할 수 있다는 장점이 있다.
예를들어 다음과 같이 똑같은 div 엘리먼트에 대해서 다른 배경색을 지정하고 싶다면 각 div마다 다른 클래스 지정자를 줄수도 있지만, 아래처럼 데이터 속성으로 직관적으로 심플하게 구성이 가능한 것이다.
<div data-columns="1"></div>
<div data-columns="2"></div>
<div data-columns="3"></div>
/* 공통 지정 */
div[data-columns] {
height: 100px;
padding: 1rem;
margin: 0 0 1rem 0;
}
/* 개별 지정 */
div[data-columns="1"] {
background: #64B5F6;
}
div[data-columns="2"] {
background: #9CCC65;
}
div[data-columns="3"] {
background: #FFB74D;
}
데이터셋 시각적인 사용
css의 attr() 함수를 통해 해당 요소의 속성을 가져올 수 있느데 데이터셋 속성도 예외가 아니다.
아래 예제는 의사 요소 선택자의 content 속성의 값으로 엘리먼트의 데이터셋 속성값을 맵핑해 지정해주는 예시이다. 이런식으로 맵핑을 하게되면 자바스크립트로 데이터셋 속성값만 변경시키면 컨텐츠 내용도 동적으로 변경하는 효과를 누릴 수 있다.
<div class="contents" data-start-date="2022-12-26" data-end-date="2023-02-28"></div>
.contents:before {
/* div.contents 엘리먼트의 data-content 속성을 가져와 표시 */
content: "이벤트 기간은 " attr(data-start-date) "일부터 " attr(data-end-date) "까지입니다.";
}
See the Pen css dataset attr by barzz12 (@inpaSkyrim) on CodePen.
데이터셋 대소문자 구분하지 않기
만일 다음과 같이 같은 단어이지만 대소문자가 다른 값인 노드들을 모두 선택하고 싶다면 대괄호 끝에 i 기호를 써주면 된다.
<div data-state="open"></div>
<div data-state="Open"></div>
<div data-state="OPEN"></div>
<div data-state="oPeN"></div>
[data-state="open" i] {
}
데이터셋 사용 주의사항
적절한 기존 특성이나 요소를 대체하는 데 사용 X
데이터셋은 자유로운 html 속성이라 제약은 거의 없다 싶지만, 만일 이미 설정되었거나 더 적절한 속성이 있는 경우 데이터 속성을 사용하지 않기를 권장하는 바다.
예를 들어 다음과 같이 시간 요소를 문서에 표현하고 싶을때, 스펙엔 <time> 이라는 태그와 적절한 datatime 이라는 속성이 있지만, 이걸 무시하고 일부러 <span> 에 데이터셋 속성을 사용하는 것은 부적절하다고 볼 수 있다.
<!-- ok -->
<time datetime="20:00">오후 8시</time>
<!-- wrong! -->
<span data-time="20:00">오후 8시<span>
검색 엔진 수집 유의사항
기본적으로 html의 데이터셋 속성은 검색엔진에서 인덱싱을 하지 않는다. 따라서 검색 엔진에 노출할 내용이나, 태그에 넣어야할 컨텐츠를 데이터셋 속성으로 표시하면 수집이 안되니 조심하여야 한다.
브라우저 호환성
IE 10 이하 에선 .dataset 프로퍼티를 지원하지 않기 때문에 호환성 유지가 필요한 경우 getAttribute()를 통해 데이터 속성을 접근해야 한다. 하지만 이러한 접근 방법의 제약으로 인해 IE 10 이하에서는 데이터셋 속성 사용은 가능하면 피하는 것이 좋다.
인터넷 익스플로러11+ 및 여타 브라우저들은 모두 표준을 지원한다.
# 참고자료
https://coding-restaurant.tistory.com/231
https://dololak.tistory.com/364
https://css-tricks.com/a-complete-guide-to-data-attributes/
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.