HTML5のdata-*属性はJavaScript用の値を要素へ持たせる
公開日: 執筆:佐藤
HTML要素とJavaScriptで使う値を対応させるには、data-*属性を使います。商品ID、表示状態、並べ替え順など、ページやアプリケーションだけが使う値を要素へ持たせるための属性です。
data-*は、見出し、ラベル、リンク先など、HTMLに用意された意味を置き換える属性ではありません。また、ページを表示した側から読んだり変更したりできるため、秘密情報や、価格、権限の正しさを保証する値にも使えません。HTMLとJavaScriptの間で、どの要素の値かを結び付けるために使います。
data-*属性はdata-の後ろへ用途を表す名前を付ける
商品詳細を開くボタンに商品IDと在庫表示用の数値を持たせるなら、次のように書けます。
<button id="detail-button"
data-product-id="A104"
data-stock-count="3">
詳細を見る
</button>
data-*属性の名前はdata-で始め、ハイフンの後ろへ一文字以上を続けます。後ろの文字列はXMLの名前として使用できる形にし、ASCIIの大文字は使いません。data-product-idやdata-stock-countのように、値の用途が分かる小文字の名前を付けます。
一つの要素には複数のdata-*属性を指定でき、値は文字列として扱われます。上のdata-stock-count="3"も、JavaScriptから読み出した直後は数値ではなく文字列です。
getAttributeはHTMLに書いた属性名をそのまま使う
属性名を変換せずに読むなら、getAttribute()を使います。
var button = document.getElementById('detail-button');
var productId = button.getAttribute('data-product-id');
var stockCount = parseInt(button.getAttribute('data-stock-count'), 10);
productIdにはA104、stockCountには数値の3が入ります。個数として加減する値は、文字列のまま計算せず、parseInt()で整数へ変換します。変換できない値が入る可能性も考え、実際の処理ではisNaN()による確認を加えます。
値を書き換える場合は、同じ属性名をsetAttribute()へ渡します。
button.setAttribute('data-stock-count', '4');
HTML側の名前とJavaScript側の名前が一致するため、どの属性を読んでいるかを追いやすい書き方です。
datasetではハイフン区切りをキャメルケースへ変える
datasetを使うと、同じ値をプロパティとして扱えます。
var productId = button.dataset.productId;
var stockCount = parseInt(button.dataset.stockCount, 10);
button.dataset.state = 'open';
delete button.dataset.state;
data-product-idはdataset.productId、data-stock-countはdataset.stockCountに対応します。data-を取り除き、ハイフンに続く小文字を大文字へ変えた名前です。datasetはDOMStringMapを返し、プロパティへ代入すると対応する属性が追加または更新されます。deleteを使えば属性も取り除かれます。
datasetで読んだ値も文字列です。"0"を真偽値のように扱ったり、"10"と"2"を文字列のまま大小比較したりせず、用途に合う型へ明示的に変換します。
対象とするブラウザーでdatasetの動作を確認できない場合は、同じdata-*属性をgetAttribute()、setAttribute()で扱います。記法を選ぶ前に、実際に必要なブラウザーで読み書きを試します。
標準属性と見える内容をdata-*で置き換えない
data-*属性は、ページやアプリケーションに固有のデータを置く場所です。リンク先にはhref、入力欄の項目名にはlabel、入力目的にはtypeなど、適切な要素や属性がある場合は、それを先に使います。
たとえば、ボタンに表示する商品名をdata-product-nameだけへ入れ、画面には表示しない構成では、HTMLを読む人に商品名が伝わりません。利用者へ伝える内容は本文やラベルとして書き、JavaScriptの処理にだけ必要な識別子をdata-*へ分けます。
スタイルを適用するためのclassへproduct-A104のような値を混ぜると、見た目の分類と処理用データの境界が曖昧になります。商品を選ぶクラスと商品IDを別に持たせると、CSSの変更でJavaScriptの値まで壊しにくくなります。
<button class="product-button" data-product-id="A104">
詳細を見る
</button>
data-*の値を注文や権限の根拠にしない
data-*属性はページのHTMLにあり、JavaScriptから変更できます。価格、在庫、割引率、操作権限を属性へ入れて表示の切り替えに使っても、その値だけを注文確定や権限判定の根拠にはできません。
たとえば、data-stock-count="3"は「残り3個」と表示する処理には使えます。注文を受け付ける時点の在庫は、サーバー側のデータを読み直して確認します。HTMLへ値を置く作業と、その値が正しいことを保証する責任を分けます。
まず、JavaScript内へ直接書いた値、class名から切り出している値、独自の非標準属性を一つ探してください。その値がページ内の処理だけに必要で、適切な標準属性がないならdata-*へ移します。文字列からの変換、値がない場合の処理、サーバー側で再確認すべき項目まで決めてから、読み書きを実装します。
関連記事

