jqMobi使い始めたけどjQueryのノリで扱うとハマったのでメモ
前提として以下のHTMLからdata-*属性を取り出すコードを書く。
ライブラリのバージョンはjQuery1.7.2、jqMobi1.2で確認。
<div id="target" data-hoge-fuga="1"></div>
生JSの場合
まず生JSの場合は以下のとおり
get
属性名を指定して取得するか、datasetから取得する2つの方法がある。
var e = document.getElementById('target');
e.getAttribute('data-hoge-fuga') // => "1"
e.dataset.hogeFuga; // => "1"
set
取得と同様に2つの方法で格納できるが、htmlに反映されると値はすべて文字列になる。
var e = document.getElementById('target');
e.setAttribute('data-hoge-fuga', 1)
e.dataset.hogeFuga = 1;
jQueryの場合
get
attr()
で取得すると文字列として取得されるが、data()
から取得すると値に応じた型で返ってくる(数字であればnumber,"true"とかだとboolにキャストされてる)
$('#target').attr('data-hoge-fuga'); // => "1"
$('#target').data('hogeFuga'); // => 1
$('#target').data('hoge-fuga'); // => 1
set
取得する際のメソッドの第2引数を与えると格納される。
$('#target').attr('data-hoge-fuga', 2); //HTMLに反映される
$('#target').data('hogeFuga', 2); //HTMLに反映されない
$('#target').data('hoge-fuga', 2); //HTMLに反映されない
ただしattr()
以外はHTMLに反映されない。
jQueryではdata-*属性の値をキャッシュされる仕様で、仮にattr()
で値をHTMLに反映させてもキャッシュされた値は変更されない。
$('#target').data('hogeFuga'); // => 1
//data()で格納
$('#target').data('hogeFuga', 2);
//data()で取得すると値は変更されている
$('#target').data('hogeFuga'); // => 2
//attr()から取得すると最初の値でHTMLも変更されない
$('#target').attr('data-hoge-fuga'); // => 1
//attr()でHTML中の値を変更
$('#target').attr('data-hoge-fuga', 2);
//HTMLの値が変更されてもキャッシュされた値は変わらない
$('#target').data('hogeFuga'); // => 1
jqMobiの場合
get
jqMobiからはキャメルケースで利用できない。内部ではdataset
から取り出すわけではなく、function(a,b){return this.attr('data-' + a, c)}
というようにattr()
を介しているので、単純に属性名から'data-'を取り除いた文字列だけで利用しなければならない。またjqueryのようにキャストされることはなく返り値はすべて文字列になる。
$('#target').data('hoge-fuga'); // => "1"
set
第2引数を与えると格納できる。キャッシュもされずHTMLに反映される。
$('#target').data('hoge-fuga', 1);
まとめ
jQueryでdata-属性を利用する場合、jQueryでオブジェクトがキャッシュされることを念頭に置く必要がある。
jqMobiから利用する場合、HTML5の仕様上はdata-*属性を取り出す際はキャメルケースに変換されたキーで取り出すのが正しいがjqMobiはそのままの形をキーとして利用しなければならない。