Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
jQuery逆引きリファレンス

jQuery逆引きリファレンス

特定の要素に関連付くデータを取得/設定するには?(data)

2015年10月22日

現在の要素に対して任意のデータを設定/取得するためのdataメソッドの基本と、利用上の注意点を解説する。

  • このエントリーをはてなブックマークに追加

 別稿「TIPS:JavaScriptとHTMLを明確に分離するには?」では、dataメソッドが独自データ属性(data-xxxxx属性)を取得するためのメソッドであると解説しました。しかし、これは厳密には正しくありません。正しくは、dataメソッドとは、現在の要素に対して任意のデータ(本稿では、便宜上、内部データと呼びます)を設定/取得するためのメソッドです。

 本稿では、dataメソッドについて別稿では解説しきれなかった内容について言及するとともに、dataメソッドを利用する際の注意点についても解説します。

dataメソッドの基本

 まずは、特定の要素に対してdataメソッドで値を設定し、その値を取得する例からです。

HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>jQuery TIPS</title>
</head>
<body>
<div id="data1">jQuery逆引きリファレンス</div>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
$('#data1').data('theme', 'reference');
console.log($('#data1').data('theme'));  // 結果:reference
</script>
</body>
</html>
dataメソッドで特定の要素に関連するデータを取得/設定するコード(data.html)

 <div id="data1">要素に対してthemeという名前でデータを設定/取得する例です。設定した値がそのままログに出力される、というごく当たり前の結果を確認できます。ただ、ここでブラウザーの開発者ツール(Chromeであれば[Elements]タブ)から文書ツリーを確認してみると、<div id="data1">要素にdata-xxxxx属性(ここではdata-theme属性)が設定されたわけではないことが確認できます。

サンプルの実行後に文書ツリーの現在の状態を確認

 dataメソッドは、あくまでjQuery内部で要素とデータのひも付けを管理するものだからです。もっと言うと、dataメソッドは取得時に指定されたキーで内部データが見つからなかった場合にだけdata-xxxxx属性を参照します。

data-xxxxx属性と内部データのキーが重複する場合

 このような性質を理解していると、以下のようなコードも自然に理解できます。

HTML
<div id="data1" data-theme="reference">jQuery逆引きリファレンス</div>
……中略……
$('#data1').data('theme', 'リファレンス');
console.log($('#data1').data('theme'));      // 結果:リファレンス1
console.log($('#data1').attr('data-theme')); // 結果:reference2
独自データ属性と内部データのキーが重複したコード(data2.html)

 この場合、対象の要素にdata-theme属性が設定されていますが、1の時点ですでに内部データとしてthemeキーが設定されていますので、dataメソッドは内部データを取得します。

 ただし、内部データthemedata-theme属性とは、本質的に別物です。よって、attrメソッドでアクセスすることで(2)、data-theme属性のもともとの値にもアクセスすることが可能です。attrメソッドでアクセスする場合、「data-」は省略できず、そのまま「data-theme」と完全な名前を指定しなければならない点に注意してください。

dataメソッドとattrメソッドの違い

 dataメソッドとattrメソッドは、独自データ属性を取得できるという意味で、一見、似た役割を持ちますが、その挙動は異なります。特に混在して利用する場合には、思わぬ挙動の原因となりますので、注意してください。

dataメソッドは値をキャッシュする

 例えば以下は、独自データ属性の値を、attrメソッドで途中変更した例です。

HTML
<div id="data1" data-theme="reference">jQuery逆引きリファレンス</div>
……中略……
console.log($('#data1').data('theme'));         // 結果:reference1
console.log($('#data1').attr('data-theme'));    // 結果:reference2
$('#data1').attr('data-theme', 'リファレンス');
console.log($('#data1').data('theme'));         // 結果:reference3
console.log($('#data1').attr('data-theme'));    // 結果:リファレンス4
独自データ属性を途中で書き換えたコード(data3.html)

 まず、12は問題ありません。attrメソッドはもちろん、dataメソッドも内部データとしてthemeキーがないので、独自データ属性data-themeの値を取得します。

 ところが、attrメソッドでdata-theme属性の値を書き換えるとどうでしょう。attrメソッドでは更新した値をきちんと返します(4)。しかし、dataメソッドは取得した値を内部データとしてキャッシュしてしまうので、data-theme属性の値にかかわらず、1で取得した値(reference)を返します(3)。

 dataメソッドが独自データ属性の値を見にいくのは、あくまで内部データとして管理されているキーがまだ存在しない場合だけです。

dataメソッドはデータ型を認識する

 例えば以下は、独自データ属性として数値/文字列/配列/オブジェクトなどを指定した例です。

HTML
<div id="data1"
  data-bool="true" data-num="15"
  data-ary='["a", "b", "c"]' data-obj='{ "a": "hoge", "b": "foo" }'>
  jQuery逆引きリファレンス</div>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
console.log('dataメソッド');
console.log($.type($('#data1').data('bool')));      // 結果:boolean
console.log($.type($('#data1').data('num')));       // 結果:number
console.log($.type($('#data1').data('ary')));       // 結果:array
console.log($.type($('#data1').data('obj')));       // 結果:object
console.log($('#data1').data('ary')[0]);            // 結果:a
console.log($('#data1').data('obj').a);             // 結果:hoge
console.log('attrメソッド');                        // 結果:attrメソッド
console.log($.type($('#data1').attr('data-bool'))); // 結果:string
console.log($.type($('#data1').attr('data-num')));  // 結果:string
console.log($.type($('#data1').attr('data-ary')));  // 結果:string
console.log($.type($('#data1').attr('data-obj')));  // 結果:string
console.log($('#data1').attr('data-ary')[0]);       // 結果:[(1文字目を取得)
console.log($('#data1').attr('data-obj').a);        // 結果:undefined
</script>
attr/dataメソッドでさまざまなデータを取得するコード(data3.html)

 dataメソッドで取得した値を$.typeメソッドで判定してみると、文字列/数字だけでなく、配列/オブジェクトも正しく認識している点に注目です。一方、attrメソッドは全ての属性を文字列として扱います。

 ただし、dataメソッドでも配列/オブジェクトのキー/値は(シングルクォートではなく)ダブルクォートでくくらなければならない点に注意してください。さもないと、正しく配列/オブジェクト型として認識できません。

[Note]jQuery 1.8より前のバージョンでは?

 jQuery 1.7.xでは、0xffのような16進数表現、1.3e-5のような指数表現も、dataメソッドではnumber型として認識していました。しかし、jQuery 1.8以降では文字列として認識されますので、もしもそのような型認識に依存するようなコードを1.7以前→1.8以降に移行する場合には注意してください。

 本文のサンプルでも見たように、-110のような10進数リテラルについては、バージョンの新旧にかかわらず、number型として認識されます。

処理対象:基本 カテゴリ:コア
API:.data() カテゴリ:データ(Data) | その他(Miscellaneous) > データストレージ(Data Storage)
API:jQuery.type() カテゴリ:Utilities(ユーティリティ)

※以下では、本稿の前後を合わせて5回分(第28回~第32回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

jQuery逆引きリファレンス
28. 要素にフォーカスが当たった/外れた時の処理を実装するには?(focus、blur、focusin、focusout)

focus/blurもしくはfocusin/focusoutを使って、テキストボックスにフォーカスを当てた時/外した時に処理を実施する方法を説明。またそれらの挙動の違いを解説する。

jQuery逆引きリファレンス
29. JavaScriptとHTMLを明確に分離するには?(data)

jQueryのdataメソッドを使って独自データ属性の値を取得することにより、「控えめなJavaScript」を実現する方法を説明する。

jQuery逆引きリファレンス
30. 【現在、表示中】≫ 特定の要素に関連付くデータを取得/設定するには?(data)

現在の要素に対して任意のデータを設定/取得するためのdataメソッドの基本と、利用上の注意点を解説する。

jQuery逆引きリファレンス
31. jQueryプラグインを自作するには?($.fn)

何度も利用する似たコードは、ライブラリではなくプラグインにまとめよう。プラグイン作成の基本を解説。

jQuery逆引きリファレンス
32. 自作のjQueryプラグインに引数を設定するには?($.extend)

プラグイン作成の基本を理解したら、パラメーターを受け取れるようにしよう。その実装方法を解説。

サイトからのお知らせ

Twitterでつぶやこう!