JavaScript
jQuery

[jQuery] data属性を動的に変更する場合の注意点

More than 3 years have passed since last update.

30分くらいはまった。


条件


  • 要素にdata属性がある。

  • data属性はある要素のアクションによって動的に変化する。


HTML

<div class="change-data" data-category="me">me</div>

<div class="change-data" data-category="my">my</div>
<div class="change-data" data-category="mine">mine</div>

<div class="get-data" data-category="i">データあるよ</div>



JavaScript

$('.change-data').on('click', function(){

$('.get-data').attr('data-category', $(this).data("category"));
});

$(document).on('click', '.get-data', function(){
console.log($(this).data('category'));
});



求める挙動


  • ロード時、.get-dataをクリックすると「i」が取得できる。

  • .change-dataをクリックすると、.get-dataのdata-categoryが変化する。

  • 再度.get-dataをクリックすると、.change-dataから取得したdata-categoryが取得できる。


実際の挙動


  • ロード時、.get-dataをクリックすると「i」が取得できる。

  • .change-dataをクリックすると、.get-dataのdata-categoryが変化する。

  • 再度.get-dataをクリックすると、問答無用で「i」(初期値) が返ってくる。


なんで?

原因は以下の通り。


  • jQueryが (?) data属性をキャッシュしている。

  • attr()メソッドで書き換えているのはHTML上の属性値だけで、jQueryオブジェクト上では上書きできていない。

えー。

ちなみに、.change-dataクリック時の処理を下記に変えてみると?


JavaScript

$('.change-data').on('click', function(){

$('.get-data').data('category', $(this).data("category"));
});


  • jQueryオブジェクト上は上書きできるが、HTML上の属性値は変化しない。

(゚Д゚) ハァ?


暫定的な解決策

data()メソッドは絶対に使わない前提で、全部attrにしちゃおうぜ!


JavaScript

$('.change-data').on('click', function(){

$('.get-data').attr('data-category', $(this).attr("data-category"));
});

$(document).on('click', '.get-data', function(){
console.log($(this).attr('data-category'));
});



真 (?) の解決策

ネイティブJSのdataset使おうぜ!


JavaScript

$('.change-data').on('click', function(){

$('.get-data')[0].dataset.category = $(this).data("category");
});

なお、datasetのサポート状況は下記の通り。

ブラウザー
バージョン

IE
11~

Firefox
6~

Chrome
7~

Safari
5.1~

Opera
11.5~

iOS
5.0~

Android
3~

古いIEやAndroidブラウザーでは、getAttributeかattr()メソッドを使えって事ですかね。

なんだこの中途半端なメソッドは……。