【JavaScript】dataset と getAttribute の違いは?data属性の取得方法と活用例
JavaScriptでUIを実装していると、「HTML要素そのものに特定のデータ(IDやカテゴリ名など)を持たせておいて、クリックされた時にJSでそのデータを読み取りたい」という場面がよくあります。 そんな時に活躍するのが、data-* 属性(カスタムデータ属性) です!
値を取得する方法として dataset と getAttribute の2種類がありますが、今回はそれぞれの違いや使い分けのポイントを解説します。「タブ切り替え」などのデモを交えて、実践的な使い方をご紹介します!
デモ動作
See the Pen data属性の取得方法と活用例 by mikanbako (@mikanbako) on CodePen.
demo: data属性の取得方法と活用例
実装コード紹介
【HTML】
<div class="l-wrap">
<h2>data属性 活用デモ</h2>
<!-- 活用例1:タブ切り替え -->
<section class="p-section">
<h3>1. タブ切り替え(表示要素の紐付け)</h3>
<ul class="c-tab-list">
<!-- 💡 data-target に表示したいコンテンツのIDを持たせる -->
<li class="c-tab-item is-active js-tab" data-target="tab-a">タブA</li>
<li class="c-tab-item js-tab" data-target="tab-b">タブB</li>
</ul>
<div class="c-tab-content is-active js-content" id="tab-a">タブAのコンテンツです。</div>
<div class="c-tab-content js-content" id="tab-b">タブBのコンテンツです。</div>
</section>
<!-- 活用例2:データ渡し -->
<section class="p-section">
<h3>2. 動的なデータ渡し(商品情報の取得)</h3>
<p>ボタンをクリックすると、持っているデータを表示します。</p>
<div class="p-btn-group">
<!-- 💡 data-item-name と data-price で情報を持たせる -->
<button class="c-btn js-item-btn" data-item-name="りんご" data-price="150">りんご</button>
<button class="c-btn js-item-btn" data-item-name="みかん" data-price="300">みかん</button>
</div>
<div class="c-msg-box js-msg-box">商品を選択してください。</div>
</section>
</div>
【CSS】
/* ベース装飾 */
.l-wrap {
max-width: 800px;
margin: 0 auto;
padding: 40px 20px;
color: #3e3e3e;
}
h2 {
font-size: 16px;
color: #1bb4d4;
text-align: center;
margin-bottom: 40px;
}
.p-section {
background: #fff;
padding: 30px;
border-radius: 8px;
margin-bottom: 40px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05);
}
h3 {
font-size: 16px;
border-bottom: 2px solid #eee;
padding-bottom: 10px;
margin-bottom: 20px;
}
p{
font-size: 16px;
margin-bottom: 20px;
}
/* 1. タブ切り替え用 */
.c-tab-list {
display: flex;
gap: 10px;
}
.c-tab-item {
padding: 10px 30px;
background: #eee;
cursor: pointer;
border-radius: 6px 6px 0 0;
font-size: 16px;
font-weight: bold;
}
.c-tab-item.is-active {
background: #1bb4d4;
color: #fff;
}
.c-tab-content {
display: none;
padding: 30px;
background: #f9f9f9;
border: 1px solid #ddd;
font-size: 16px;
}
.c-tab-content.is-active {
display: block;
}
/* 2. データ渡し用 */
.p-btn-group {
display: flex;
gap: 16px;
margin-bottom: 20px;
}
.c-btn {
padding: 10px 20px;
background: #e83e8c;
color: #fff;
font-size: 16px;
font-weight: bold;
border-radius: 4px;
cursor: pointer;
}
.c-msg-box {
padding: 13px;
background: #222;
color: #0f0;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
}
【JavaScript】
/* =========================================
1. タブ切り替え(data-target の活用)
========================================= */
const tabs = document.querySelectorAll('.js-tab');
const contents = document.querySelectorAll('.js-content');
tabs.forEach((tab) => {
tab.addEventListener('click', (e) => {
// 💡 datasetを使って、クリックされたタブの data-target の値を取得
// HTML: data-target="tab-a" -> JS: dataset.target
const targetId = e.currentTarget.dataset.target;
// タブのアクティブ状態をリセット&付与
tabs.forEach(t => t.classList.remove('is-active'));
e.currentTarget.classList.add('is-active');
// コンテンツの表示を切り替え
contents.forEach(content => {
content.classList.remove('is-active');
// 取得した targetId と同じ ID を持つコンテンツだけ表示!
if (content.id === targetId) {
content.classList.add('is-active');
}
});
});
});
/* =========================================
2. 動的なデータ渡し(data-item-name, data-price の活用)
========================================= */
const itemBtns = document.querySelectorAll('.js-item-btn');
const msgBox = document.querySelector('.js-msg-box');
itemBtns.forEach((btn) => {
btn.addEventListener('click', (e) => {
// 💡 HTML側の data-item-name は、JS側では itemName になります!
const name = e.currentTarget.dataset.itemName;
const price = e.currentTarget.dataset.price;
// 取得したデータを使ってメッセージを表示
msgBox.textContent = `選択された商品: ${name} / 価格: ${price}円`;
});
});
コード解説
今回のデモでは、取得した data 属性の値をそれぞれ次のように活用しています。
タブ切り替え(IDとの照合)
// 💡 datasetを使って、クリックされたタブの data-target の値を取得
// HTML: data-target="tab-a" -> JS: dataset.target
const targetId = e.currentTarget.dataset.target;
...
// コンテンツの表示を切り替え
contents.forEach(content => {
content.classList.remove('is-active');
// 取得した targetId と同じ ID を持つコンテンツだけ表示!
if (content.id === targetId) {
content.classList.add('is-active');
}
});
e.currentTarget.dataset.target で、クリックされたタブに設定されている data-target の値(例:tab-a)を取得しています。 その後、すべてのコンテンツを順番にチェックし、「取得した値」と「コンテンツ自身の id」が一致するもの(content.id === targetId)だけに is-active クラスを付けて表示させています。タブ実装における王道のロジックです!
動的なデータ渡し(テンプレートリテラルでの展開)
// 💡 HTML側の data-item-name は、JS側では itemName になります!
const name = e.currentTarget.dataset.itemName;
const price = e.currentTarget.dataset.price;
// 取得したデータを使ってメッセージを表示
msgBox.textContent = `選択された商品: ${name} / 価格: ${price}円`;
dataset.itemName と dataset.price でボタンから取得したデータを、バッククォート(`)で囲んだ文字列の中に ${name} のように埋め込んで出力しています。 この仕組みを使えば、ECサイトの商品一覧からモーダルウィンドウを開く時など、「クリックした要素のデータを読み取って、別の場所に表示する」という処理がたった一つの関数で使い回せるようになります!
dataset と getAttribute の違いと使い分け
基本は dataset を使おう!
HTMLに <div data-sample-value="test"></div> と書かれている場合、どちらの方法でも値"test"を取得できます。
dataset プロパティを使う場合(推奨)
// HTML: data-sample-value
// JS : キャメルケース(sampleValue)に変換される!
const value = element.dataset.sampleValue;
getAttribute() メソッドを使う場合
// HTMLの属性名をそのまま文字列で指定する
const value = element.getAttribute('data-sample-value');
短くて直感的に書ける dataset を使うのが主流です。
最大の注意点は、dataset を使う場合、HTML側でハイフン繋ぎ(ケバブケース)だった名前が、JS側ではキャメルケースに自動変換されるという点です!
getAttribute はいつ使うの?
基本は dataset でOKですが、以下のような少し特殊なケースでは getAttribute 系が役立ちます。
element.removeAttribute('data-sample-value')のように、属性そのものをHTMLから完全に削除したい時。- CSSのセレクタとしてそのまま文字列で扱いたい時など。
補足:公式ドキュメント
より詳しい仕様や最新の対応状況については、以下の公式ドキュメントをご参照ください。
まとめ
今回は data 属性の取得方法の違いと、活用例をご紹介しました。
JavaScriptでHTMLの要素を操作する際、要素自身に必要なデータを持たせておくことで、コードがとてもシンプルで管理しやすくなります。基本的にはキャメルケースで短く書ける dataset を使いこなしつつ、状況に合わせて上手く使い分けていきましょう!