jQuery逆引きリファレンス
特定の要素に関連付くデータを取得/設定するには?(data)
現在の要素に対して任意のデータを設定/取得するためのdataメソッドの基本と、利用上の注意点を解説する。
別稿「TIPS:JavaScriptとHTMLを明確に分離するには?」では、data
メソッドが独自データ属性(data-xxxxx
属性)を取得するためのメソッドであると解説しました。しかし、これは厳密には正しくありません。正しくは、data
メソッドとは、現在の要素に対して任意のデータ(本稿では、便宜上、内部データと呼びます)を設定/取得するためのメソッドです。
本稿では、data
メソッドについて別稿では解説しきれなかった内容について言及するとともに、data
メソッドを利用する際の注意点についても解説します。
dataメソッドの基本
まずは、特定の要素に対してdata
メソッドで値を設定し、その値を取得する例からです。
<!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>
|
<div id="data1">
要素に対してthemeという名前でデータを設定/取得する例です。設定した値がそのままログに出力される、というごく当たり前の結果を確認できます。ただ、ここでブラウザーの開発者ツール(Chromeであれば[Elements]タブ)から文書ツリーを確認してみると、<div id="data1">
要素にdata-xxxxx属性
(ここではdata-theme
属性)が設定されたわけではないことが確認できます。
data
メソッドは、あくまでjQuery内部で要素とデータのひも付けを管理するものだからです。もっと言うと、data
メソッドは取得時に指定されたキーで内部データが見つからなかった場合にだけ、data-xxxxx
属性を参照します。
data-xxxxx属性と内部データのキーが重複する場合
このような性質を理解していると、以下のようなコードも自然に理解できます。
<div id="data1" data-theme="reference">jQuery逆引きリファレンス</div>
……中略……
$('#data1').data('theme', 'リファレンス');
console.log($('#data1').data('theme')); // 結果:リファレンス1
console.log($('#data1').attr('data-theme')); // 結果:reference2
|
この場合、対象の要素にdata-theme
属性が設定されていますが、1の時点ですでに内部データとしてtheme
キーが設定されていますので、data
メソッドは内部データを取得します。
ただし、内部データtheme
とdata-theme
属性とは、本質的に別物です。よって、attr
メソッドでアクセスすることで(2)、data-theme
属性のもともとの値にもアクセスすることが可能です。attr
メソッドでアクセスする場合、「data-」は省略できず、そのまま「data-theme」と完全な名前を指定しなければならない点に注意してください。
dataメソッドとattrメソッドの違い
data
メソッドとattr
メソッドは、独自データ属性を取得できるという意味で、一見、似た役割を持ちますが、その挙動は異なります。特に混在して利用する場合には、思わぬ挙動の原因となりますので、注意してください。
dataメソッドは値をキャッシュする
例えば以下は、独自データ属性の値を、attr
メソッドで途中変更した例です。
<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
|
まず、12は問題ありません。attr
メソッドはもちろん、data
メソッドも内部データとしてtheme
キーがないので、独自データ属性data-theme
の値を取得します。
ところが、attr
メソッドでdata-theme
属性の値を書き換えるとどうでしょう。attr
メソッドでは更新した値をきちんと返します(4)。しかし、data
メソッドは取得した値を内部データとしてキャッシュしてしまうので、data-theme
属性の値にかかわらず、1で取得した値(reference)を返します(3)。
data
メソッドが独自データ属性の値を見にいくのは、あくまで内部データとして管理されているキーがまだ存在しない場合だけです。
dataメソッドはデータ型を認識する
例えば以下は、独自データ属性として数値/文字列/配列/オブジェクトなどを指定した例です。
<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>
|
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以降に移行する場合には注意してください。
本文のサンプルでも見たように、-11
、0
のような10進数リテラルについては、バージョンの新旧にかかわらず、number
型として認識されます。
API:.data() カテゴリ:データ(Data) | その他(Miscellaneous) > データストレージ(Data Storage)
API:jQuery.type() カテゴリ:Utilities(ユーティリティ)
※以下では、本稿の前後を合わせて5回分(第28回~第32回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
28. 要素にフォーカスが当たった/外れた時の処理を実装するには?(focus、blur、focusin、focusout)
focus/blurもしくはfocusin/focusoutを使って、テキストボックスにフォーカスを当てた時/外した時に処理を実施する方法を説明。またそれらの挙動の違いを解説する。
29. JavaScriptとHTMLを明確に分離するには?(data)
jQueryのdataメソッドを使って独自データ属性の値を取得することにより、「控えめなJavaScript」を実現する方法を説明する。