かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

JavaScript data-属性の操作

VDOMなフレームワークを使っているとHTMLの属性を直接触る機会はあまりないと思いますが、カスタムデータ属性 data-* の操作には getAttribute / setAttribute より dataset を使うと簡単です。

カスタムデータ属性 data-*

カスタムdata属性の名前はdata-で始まる。また、カスタムdata属性名は文字、数字とダッシュ(-)、ドット (.)、コロン (:)、アンダースコア (_)しか含むことができない。さらに、ASCIIコードの大文字AからZも含むことができない。
ref. HTMLElement.dataset - Web API | MDN

dataset

Element.dataset でカスタムデータ属性が key: value で入ったオブジェクトとして扱える

<div id="elm"
  data-name="Hoshimiya Ichigo"
  data-type="cute"
  data-name-ja="星宮いちご">
</div>
const elm = document.getElementById('elm');
console.log(elm.dataset);
/* DOMStringMap
{
  name: "Hoshimiya Ichigo"
  nameJa: "星宮いちご"
  type: "cute"
}
*/

ハイフン繋のカスタムデータはkeyがキャメルケースに変換される。

データの取得と変換

dataset はオブジェクトなので、通常のオブジェクトのようにカスタムデータ属性の取得・更新を行うことができる

<div id="elm"
  data-name="foo"
  data-my-val="bar"
  data-count="0"
></div>
data-* の取得
const elm = document.getElementById('elm');
elm.dataset.name; // => "foo"
elm.dataset.myVal; // => "bar"
elm.dataset.count; // => "0"
data-* の更新
elm.dataset.name = 'bar';
elm.dataset.myVal += 'ely';
// => <div id="elm" data-name="bar" data-my-val="barely" data-count="0"></div>

カスタムデータは文字列で取得されるので扱いには注意が必要

elm.dataset.count += 1;
// elm.dataset.count は "0" なので文字列結合される
// => <div id="elm" data-name="bar" data-my-val="barely" data-count="01"></div> 
data-* 属性の追加

存在しないキーに値を渡すと DOM にカスタムデータ属性が追加される。
キャメルケースの key は ハイフン - つなぎに変換されて DOM に追加される。

// <div id="elm"></div>
const elm = document.getElementById('elm');
elm.dataset.name = "foo";
elm.dataset.someVal = "bar";
// => <div id="elm" name="foo" data-some-val="bar"></div>
data-* 属性の削除

Element.dataset で空文字を入れても属性そのものは削除されない

// <div id="elm" name="foo"></div>
const elm = document.getElementById('elm');
elm.dataset.name = "";
// => <div id="elm" name></div>
elm.dataset;
// => DOMStringMap {name: ""}

nullundefinedNaN を渡すと"null", "undefined", "NaN"という文字列がカスタムデータ属性の値として設定される

カスタムデータ属性自体を削除するには delete 演算子removeAttribute を使う

delete elm.dataset.name;
// 又は
elm.removeAttribute('data-name');
// => <div id="elm"></div>
elm.dataset;
// => DOMStringMap {}

カスタムデータ属性の名前が正しくない場合

e.g. キャメルケースになっている場合

<div id="elm" data-idolName="霧矢あおい"></div>
const elm = document.getElementById('elm');
elm.dataset.idolName; // => undefined
elm.getAttribute('data-idolName'); // => "霧矢あおい"

Element.dataset ではそのままの key で値を取得することができない。

キャメルケースになっている key は lowercase されている

console.log( elm.dataset );
// => DOMStringMap {idolname: "霧矢あおい"}
elm.dataset.idolname; //=> "霧矢あおい"
まとめ

Element.dataset を使うとオブジェクトを扱うように カスタムデータ属性 (data-*)が扱えるのでとても良さげです。
だだし、大文字は使えないことになっているのに違反しているようなカスタムデータ属性が使われている場合、注意が必要そうです。(HTML側を修正するようにPRするか、レビューで通さないようにするのが良いと思います)


[参考]

Kiss Me/Hold Me Now

Kiss Me/Hold Me Now

  • アーティスト: キャロル&チューズデイ(Nai Br.XX&Celeina Ann)
  • 出版社/メーカー: フライングドッグ
  • 発売日: 2019/05/29
  • メディア: CD
  • この商品を含むブログを見る
👆今期やってるアニメの キャロル&チューズデイ がとても良い