そんなにGeekじゃないエンジニアブログ

HTMLのタグに任意の属性を付与する。カスタムデータ属性で独自のdataを扱う方法とjQueryでの注意点

calendar

こんにちは。でんすけ(@notgeek_densuke)です。

HTMLのタグに好きなデータを付与しておきたい場面があるかと思いますが。
そんな時はカスタムデータ属性を使うといいよ、という話です。

スポンサーリンク

カスタムデータ属性とは

カスタムデータ属性とは、こんなやつです。

<div data-mydata="hogehoge">DIVにhogehogeっていうデータを付けたよ</div>

こんな感じで、HTMLタグの属性には
data-好きな名前」という形式で、任意の属性を付けることができます。

名前は任意ですが、大文字は使えないことに注意です。
ハイフンで区切ることはできるので、「mydata-first」のような名前はOK。

JavaScriptでのカスタムデータ属性の扱い方

JavaScriptでカスタムデータ属性を扱うには、大きく分けて2つの手段があります。

・datasetを使う
・getAttribute、setAttributeを使う

実例を以下に。

<div id="mydiv" data-mydata="hogehoge" data-mydata-second="foobar">DIVにカスタムデータを付けたよ</div>

<script>
	var elem = document.getElementById("mydiv");

	/*** カスタムデータ属性からデータの取得 ***/
	console.log( "datasetを使う方法:" + elem.dataset.mydata + elem.dataset.mydataSecond );
	console.log( "getAttributeを使う方法:" + elem.getAttribute('data-mydata') + elem.getAttribute('data-mydata-second') );


	/*** カスタムデータ属性の編集、datasetを使う場合 ***/
	elem.dataset.mydata = "rewrite"; //data-mydataを上書き
	elem.dataset.mydataThird = "3rd data"; //data-mydata-thirdを新規追加

	console.log( "datasetでデータ編集後:" + elem.getAttribute('data-mydata') + elem.getAttribute('data-mydata-third') );


	/*** カスタムデータ属性の編集、setAttributeを使う場合 ***/
	elem.setAttribute("data-mydata", "ReRewrite"); //data-mydataを上書き
	elem.setAttribute("data-mydata-fourth", "4th data"); //data-mydata-fourthを新規追加

	console.log( "setAttributeでデータ編集後:" + elem.dataset.mydata + elem.dataset.mydataFourth );
</script>

datasetで扱う場合、ハイフンで区切った直後を大文字にして扱うことになります。
この、単語の区切り部分を大文字にすることはキャメルケースと呼ばれます。

そのルールさえ守れば、datasetでも、set or get Attributeでも、どちらも使い方はそれほど変わらないので、お好きな方で。

jQueryでのカスタムデータ属性の扱い方

jQueryだと

・data()を使う
・attr()を使う

という2種類。

ただ、jQueryでは、データの変更の挙動がちょっと怪しくなります。
こんな感じ。

<div id="mydiv" data-mydata="hogehoge" data-mydata-second="foobar">DIVにカスタムデータを付けたよ</div>

<script>
	jQuery(function($){
		var $elem = $("#mydiv");

		/*** データの取得 ***/
		console.log( $elem.data("mydata") );
		console.log( $elem.data("mydata-second") );
		console.log( $elem.data("mydataSecond") );

		console.log( $elem.attr("data-mydata") );
		console.log( $elem.attr("data-mydata-second") );

		console.log( $elem.data() ); //JSON形式で一気に取得
		console.log( $elem.data().mydata );
		console.log( $elem.data().mydataSecond );
		/*** データの取得だけなら問題なし ***/


		/*** 新しいデータの追加 ***/
		$elem.data("mydataThird", "3rd data");
		$elem.data("mydata-fourth", "4th data");

		$elem.attr("data-mydata-fifth","5th data");

		console.log( $elem.data("mydata-fifth") ); //5th dataが表示される

		console.log( $elem.attr("data-mydata-third") ); //undefined!!
		console.log( $elem.attr("data-mydata-fourth") ); //undefined!!
		//実際DOMを確認すると<div id="mydiv" data-mydata="rewrite" data-mydata-second="foobar" data-mydata-fifth="5th data">となって、属性が付与されていない


		/*** 既存データの書き換え ***/
		$elem.attr("data-mydata", "rewrite");
		console.log( $elem.data("mydata") ); //書き換えたのにhogehogeのまま!
		console.log( $elem.attr("data-mydata") ); //こっちだとrewriteになってる

		$elem.data("mydataSecond", "ReRewrite");
		console.log( $elem.attr("data-mydata-second") ); //書き換えたのにfoobarのまま!
		console.log( $elem.data("mydata-second") );  //こっちだとReRewriteになってる
	});
</script>

キャメルケースでもハイフンでも、どちらでも柔軟にやってくれて便利っぽいのですが、
データの書き換えで、ちょっと挙動がややこしい。

jQueryのdata()は、一応カスタムデータ属性からデータを取得できるのですが、
実際にDOMの属性値を書き換えるわけではないっぽい挙動をしています。
jQueryオブジェクト内の「data」属性を書き換えているだけっぽい?

attr()を使ってのDOMの属性値を書き換えることはできますが、
jQueryオブジェクト内の「data」にデータが残っている場合は、それを書き換えないっぽい。
なので、DOMの属性値は書き換わっているけど、jQueryオブジェクト内の「data」を優先して見に行くので
思ったデータが取得できない、という感じ。

せっかく便利っぽいのに、どうもややこしい動きをするので、使う場合は注意が必要です。
値を書き換える場合は、jQueryは使わない方がいいかも。

独自の属性の使い方

さて、カスタム属性、何が便利かというと。
まぁ色んな使い方ができると思いますが。

たとえば、一覧にしたいデータがあったとして。
そこに、IDナンバーや、種類、その他情報を載せておくことができます。

たとえば、スプラトゥーンのブキの一覧があるとして。

<div class="spla-weapon" data-idnum="001" data-type="シューター" data-sub="クイックボム">スプラシューター</div>
<div class="spla-weapon" data-idnum="002" data-type="シューター" data-sub="スプラッシュボム">スプラシューターコラボ</div>
<div class="spla-weapon" data-idnum="003" data-type="マニューバー" data-sub="クイックボム">スプラマニューバー</div>
<div class="spla-weapon" data-idnum="004" data-type="シューター" data-sub="ポイントセンサー">.52ガロン</div>

こんな感じで。
これで、見た目は変えずに、いろんな情報を載せることができます。

例えば、データを使って順番を並べ替えたりも。

<div id="spla-weaponlist">
	<div class="spla-weapon" data-idnum="001" data-type="シューター" data-sub="クイックボム">スプラシューター</div>
	<div class="spla-weapon" data-idnum="002" data-type="シューター" data-sub="スプラッシュボム">スプラシューターコラボ</div>
	<div class="spla-weapon" data-idnum="003" data-type="マニューバー" data-sub="クイックボム">スプラマニューバー</div>
	<div class="spla-weapon" data-idnum="004" data-type="シューター" data-sub="ポイントセンサー">.52ガロン</div>
</div>
<button name="idsort">IDでソート</button>
<button name="typesort">種別でソート</button>
<button name="subsort">サブでソート</button>

<script>
	jQuery(function($){
		$("button[name='idsort']").click(function(){
			$("#spla-weaponlist").html(
				$(".spla-weapon").sort(function(a,b){
					return ($(a).data("idnum") < $(b).data("idnum") ? 1 : -1);
				})
			);
		});
		$("button[name='typesort']").click(function(){
			$("#spla-weaponlist").html(
				$(".spla-weapon").sort(function(a,b){
					return ($(a).data("type") < $(b).data("type") ? 1 : -1);
				})
			);
		});
		$("button[name='subsort']").click(function(){
			$("#spla-weaponlist").html(
				$(".spla-weapon").sort(function(a,b){
					return ($(a).data("sub") < $(b).data("sub") ? 1 : -1);
				})
			);
		});
	});
</script>

若干やっつけなソースですが。。
いずれにせよ、一つのHTMLタグの中に複数の情報を持っておくことができるので、
より動的な操作をしやすくなる、ということです。

まとめ

ということで、カスタムデータ属性の話でした。

なにかと便利なので使ってみてください。

それではまたー。

この記事をシェアする

コメント

コメントはありません。

down コメントを残す




CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください