• HTML5のdata-*属性はJavaScript用の値を要素へ持たせる

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-*へ移します。文字列からの変換、値がない場合の処理、サーバー側で再確認すべき項目まで決めてから、読み書きを実装します。

戻る