Javascript:カスタムデータ属性で配列(実は文字列)の受け渡し

Javascript の小ネタです。

HTML から Javascript へのデータの受け渡しに複数のデータを渡すことは出来ないかという話です。



カスタムデータ属性の値はひとつ

HTML5 から導入されたカスタムデータ属性は HTML から Javascript や CSS にデータを渡せますのでとても便利なものです。


MDN のサンプルですが、

<article
  id="electric-cars"
  data-columns="3"
  data-index-number="12314"
  data-parent="cars">
...
</article>


こうした HTML があった場合、Jvascript でカスタムデータ属性の値を受け取ることが出来ます。


const article = document.getElementById('electric-cars');

article.dataset.columns // "3"
article.dataset.indexNumber // "12314"
article.dataset.parent // "cars"



ただし、この例のようにひとつの属性に設定できる値はひとつだけです。

最後に追記)というよりも、この記事の最後にわかったことですが、値は文字列でしか渡せないということで、jQuery の data() メソッドを使いますと型変換をしてしまいますので、配列形式にするとあたかも配列で渡しているように見えるだけです。


値を配列で渡す

で、今回、複数のデータを Javascript に渡せないかとググりましたら、配列やオブジェクト形式にすれば渡せるということがわかりました。

いくつかヒットしますが最初にヒットした記事をリンクしておきます。



注意事項は、たとえば、data-text = '["text1","text2","text3"]' のように配列をシングルクォーテーションでくくり、個々の値をダブルクォーテーションでくくらなければならないようです。

で、問題は Javascript での受け取り方ですが、jQuery を使えば、data() で配列として取り出せますが、素の Javascript では文字列になってしまいます。

具体的には、上の例の dataset.text は、["text1","text2","text3"] の文字列でしか取り出せません。考えてみれば当然かもしれません。配列として送っているのではなく、文字列で送っているだけで、それを jQuery が配列とみなしているだけなのかなあと思います。


match() メソッドで配列化する

じゃあ、素の Javascript でも文字列を配列化すればいいのではないかということで match() メソッドでやってみましたらうまくいきました。

正規表現の肯定後読み、肯定先読みを使っています。


const re = /(?<=\")[^,\s].*?(?=\")/g;
const matches = 要素名.dataset.text.match(re);

console.log(matches);
// Array ["text1", "text2", "text3"]

となります。

Javascript の小ネタでした。


配列形式にする必要ないんじゃない?

ん? そもそも文字列でしか渡らないのであれば、配列形式にせずに data-text = "text1,text2,text3" で渡して、dataset.text.split(',') で配列に変換すればいいんじゃないか?


<div id="sample" data-text="text1,text2,text3">
...
</div>
const sample = document.getElementById('sample');
const array = sample.dataset.text.split(',');

console.log(array);
// Array ["text1", "text2", "text3"]


その通りでした! 素の Javascript であればこれでいけます。