ROCHAS

HTML5 カスタムデータ属性「data-*」にJavaScript、jQueryからアクセスする方法

HTML5ではdata-*="value"の形式で属性名にプライベートな値を設定できるカスタムデータ属性の仕様と、そのカスタムデータ属性にJavaScriptからアクセスするAPIが定義されました。 でも実はJavaScriptだけではなく、jQueryはもちろんCSSからでもアクセスすることができるのです。 それなら私も私だけの属性作ってみたい!
ということで、今回から連載で、JavaScript、jQuery、CSSからカスタムデータ属性にアクセスする方法と、ごくごく簡単なツールチップが実装できるコンポーネントをご紹介します。

1. HTML5 カスタムデータ属性「data-*=“value"」とは

カスタムデータ属性には、既存の要素や属性に適切なものがなかった場合に、独自のデータを属性に格納することで、より意味を持たせる意図があります。全てのHTML要素に対し、複数設定することができます。
data-*="value"
カスタムデータ属性が自由に作れるといっても規則があります。必ずdata-から始まり、その後ろにはXML-compatibleの属性命名規則に則りまして、1文字以上のアルファベット、数字、ハイフン、アンダースコアを文字列に指定することができます。ただし文字列の先頭は小文字のアルファベットでなければなりません。そう、他と競合してはいけないのです。
といっても普通の属性とどう違うのかピンとこないかもしれませんが、HTML側で指定したカスタムデータ属性はJavaScript、jQuery、CSSに受け渡し、処理を行うことで本領を発揮するのです。
それでもよくわからないという場合はBootstrap JavaScriptやjQuery Mobileを見ていただくとイメージが沸くと思います。
jQuery Mobileではa要素にと指定するだけでボタンとしての機能やデザインを持ったものに変身し、またその属性値をに変えれば、ポップアップが表示できるといったように、使い回しもできてしまうのです。それはカスタムデータ属性に紐付けされたjQueryがそれぞれの属性値ごとに個別に処理を行っているからなのです。
スニペット以上、プラグイン未満って言うか・・・つまりコンポーネントを作るのにカスタムデータ属性はとても便利なのです。

2. Demo:カスタムデータ属性とjQueryでつくったツールチップのコンポーネント

こちらがマウスオーバーで吹き出しが表示する、jQueryでつくったコントーポーネントです。
吹き出しを表示したい要素に「data-tooltip」属性を指定するだけで、同じ機能とデザインを持ったツールチップにそれぞれ個別なテキストを表示させる、ごくシンプルなものです。

Demo | カスタムデータ属性とjQueryでつくったツールチップ

この他にも当ブログで、カスタムデータ属性「data-*」を使ってRetina対応する方法の記事や、実践編としてコンポーネントの作り方なども記事に書いています。

SVGをフォールバック画像に一括変換するjQueryスニペット | Dress Cording

3. JavaScriptでカスタムデータ属性にアクセスする2つの方法とその違い

JavaScriptでカスタムデータ属性にアクセスするには、dataset IDL属性を使う方法とgetAttribute() / setAttribute()メソッドを使う方法の2つあります。
dataset IDL属性は、HTML5 APIで定義されたカスタムデータ属性専用のアクセサーで、とてもシンプルに記述することができます。IDL属性とは、JavaScriptからHTML内の要素をDOMに基づいて操作する際に、JavaScriptオブジェクトから利用されるオブジェクト・プロパティのことです。 ただしIE9からの対応となりますので、もしIE8以下に対応させるならばdataset IDL属性ではなくgetAttribute() / setAttribute()を使ってをアクセスする必要があります。

4. [JavaScript] dataset IDL属性でカスタムデータ属性にアクセスする方法

element.dataset.camelCase;

dataset IDL属性は、要素からHTML側で指定したカスタムデータ属性の値をDOMStringMapオブジェクトとして返します。
datasetの後ろにdata-以降の文字列をドットで繋ぎます。カスタムデータ属性にはハイフンが使えると言いましたが、JavaScript側ではキャメルケースに変換しなければなりません。dataを外し、ハイフンを含む場合はハイフンを取って、次の文字を大文字にします。ラクダのコブのように。 キャメルケース'data-dog-breed' ⇒ dogBreedカスタムデータ属性をキャメルケースに変換するdataset IDL属性に対し、getAttribute() / setAttribute()メソッドは文字列をそのまま引数に代入する点が違うので注意が必要です。
またdataset IDL属性はこれひとつでカスタムデータ属性の値の取得、設定、削除と3つの役割を果たします。 ここもgetAttribute() / setAttribute()と違う点です。
その辺りの違いに注目してコードを見て頂くとわかりやすいと思います。

HTML側で指定したカスタムデータ属性をDOMから削除するにはdatasetにnullを設定します。

// nullを設定するとDOMからカスタムデータ属性を削除
mydog.dataset.name = null; // 特に名前はない

5. [JavaScript] getAttribute() / setAttribute()でカスタムデータ属性にアクセスする方法

element.getAttribute('data-name')

element.setAttribute('data-name','value');

getAttribute()でカスタムデータ属性の値を取得するには、引数はキャメルケースに変換せず、そのまま data-を含めた文字列を'data-count'のように指定します。
setAttribute()で新しいカスタムデータ属性を設定、第2引数を指定した場合には属性値をその値に変更します。 また、カスタムデータ属性を削除するにはremoveAttribute()を使用します。

6. querySelectorAll()でカスタムデータ属性から要素を取得する

ちなみにquerySelectorAll()の引数にカスタムデータ属性を指定すると、その要素を取得することができます。ただしIE7以下は非対応です。

// 属性が'data-dog-breed'である要素を全てを取得
document.querySelectorAll('[data-dog-breed]');

// 属性値が"poodle"である要素を全てを取得
document.querySelectorAll('[data-breed="poodle"]');

jQueryでカスタムデータ属性にアクセスするにもdata()を使う方法とattr()を使う方法の2つあります。
Data APIで定義されたdata()は、カスタムデータ属性の値をjQuery内のキャッシュにデータとして取得、保存します。それに対してattr()はカスタムデータ属性の値を文字列で取得、設定します。 いったいどう記述の方法が違って、どう使い分ければいいの?というところを見ていきたいと思います。

8. [jQuery] data()でカスタムデータ属性にアクセスする方法

.data('camelCase')

.data('camelCase','value')

jQueryのdata()は属性値を、jQuery内のキャッシュのJavaScriptオブジェクトにデータとして保存、取得します。 data()でカスタムデータ属性の値を取得するにはdata()の引数にdata-以降の文字列を指定し、ハイフンを含む場合はハイフンを取って、次の文字を大文字にします。キャメルケースですね。 また第2引数を指定した場合には属性値を保存します。

9. [jQuery] attr()でカスタムデータ属性にアクセスする方法

.attr('data-name')

.attr('data-name','value')

カスタムデータ属性の値をattr()で取得する場合は、引数はキャメルケースに変換せず、そのままdata-を含めた文字列を'data-type-str'のように指定します。また第2引数を指定した場合には属性値を保存します。
data()attr()の記述の方法の違いは引数にキャメルケースに変換するか、文字列のまま代入するかです。 次はどう使い分けるかを見ていきます。

10. data()は暗黙のうちに文字列、数値、真偽値、オブジェクト、配列に型変換される

カスタムデータ属性の値をdata()で保存、取得すると、その値は暗黙のうちに文字列、数値、オブジェクト、配列に型変換されます。
なぜこんなことが起きるのかといいますと、HTML側から設定したカスタムデータ属性の値は文字列として解釈され、それがdata()を介することによって、文字列、数値、真偽値、オブジェクト、配列といったJavaScriptオブジェクトが扱える任意のデータ型に変換されるためです。 「007」で例えてみるとdata()は「7」と数値に変換され、attr()は「007」のまま文字列として扱われます。
つまり、数を数値として扱いたい場合はdata()を、数を文字列として扱いたい場合はattr()を使います。真偽値、オブジェクト、配列もしかりです。

カスタムデータ属性を取得する時のdata()attr()の使い分けはわかりました。次に削除する時を見ていきます。

11. HTML属性を完全に削除するにはremoveAttr()、removeData()の2段階で削除する

jQueryのremoveData()、removeAttr()とも、引数に指定した値を削除、何も指定しなければ全てを削除します。ですがこの2つは削除する対象が違うのでここも注意が必要です。
data()によってjQuery内のキャッシュに保存されたデータを削除する場合にはremoveData()を使います。ただしremoveData()ではHTML側で設定したカスタムデータ属性を削除することはできません。また逆に言うとremoveAttr()ではjQuery内のキャッシュに保存されたデータは削除できません。
HTML属性を完全に削除するにはremoveAttr()で削除してからremoveData()で削除する必要があります。

12. カスタムデータ属性をセレクタに指定する

もちろんカスタムデータ属性をセレクタに指定して、その要素を取得することができます。

// 属性が'data-type-str'である要素を全てを取得
$('[data-type-str]').css('color','pink')

// 属性値が"movie"である要素を全てを取得
$('[data-type-str="movie"]').css('color','pink')

今回はJavaScriptからカスタムデータ属性へのアクセスする方法の話しでしたが、実はCSSでも取得できるしので、これから使用頻度も増えてきそうです。

参考サイト