javascript / jQueryを使用してdata- *属性のリストを取得する


150

0個以上のdata-*属性を持つ任意のHTML要素が与えられた場合、データのキーと値のペアのリストを取得するにはどうすればよいでしょうか。

例えばこれを与えられた:

<div id='prod' data-id='10' data-cat='toy' data-cid='42'>blah</div>

これをプログラムで取得できるようにしたいと思います。

{ "id":10, "cat":"toy", "cid":42 }

jQuery(v1.4.3)を使用する$.data()場合、キーが事前にわかっていれば、データの個々のビットへのアクセスは簡単ですが、任意のデータセットを使用してこれを行う方法は明らかではありません。

「単純な」jQueryソリューションが存在する場合はそれを探していますが、それ以外の場合は低レベルのアプローチを気にしません。解析しようと試みました$('#prod').attributesが、javascript-fuの欠如は私を失望させています。

更新

カスタムデータは必要なことを行います。ただし、jQueryプラグインをその機能の一部にのみ含めることは、やり過ぎのように思えました。

ソースを目視することで、自分のコードを修正することができました(そして、javascript-fuを改善しました)。

これが私が思いついた解決策です:

function getDataAttributes(node) {
    var d = {}, 
        re_dataAttr = /^data\-(.+)$/;

    $.each(node.get(0).attributes, function(index, attr) {
        if (re_dataAttr.test(attr.nodeName)) {
            var key = attr.nodeName.match(re_dataAttr)[1];
            d[key] = attr.nodeValue;
        }
    });

    return d;
}

アップデート2

受け入れられた回答で示されているように、ソリューションはjQuery(> = 1.4.4)の場合は簡単です。$('#prod').data()必要なデータ辞書を返します。


jquery data()が内部キャッシュを使用し、data(key、value)がDOMに伝達されないことに注意して「更新2」を追加すると、多くの問題が発生する可能性があります。また、jquery 3 data()が属性data-some-thing = "test"を{someThing: "test"}に変換するため
ETNyx

回答:


96

実際、jQueryを使用している場合は、バージョン 1.4.31.4.4(以下のコメントに記載されているバグのため)、data-*属性はを通じてサポートされます.data()

jQuery 1.4.3以降、HTML 5 data- 属性は自動的にjQueryのデータオブジェクトに取り込まれます。

JavaScript値が関連付けられた値に変換される間、文字列はそのまま残ります(これには、ブール値、数値、オブジェクト、配列、およびnullが含まれます)。data- 属性が最初に引っ張られるデータプロパティがアクセスされていないと、もはや(すべてのデータ値は、その後のjQueryの内部に格納されている)アクセスまたは突然変異しています。

このjQuery.fn.data関数はdata-、オブジェクト内のすべての属性をキーと値のペアとして返します。キーは後の属性名の一部でdata-あり、値は上記のルールに従って変換された後のその属性の値です。

それがあなたを納得させないなら、私は簡単なデモも作成しました:http : //jsfiddle.net/yijiang/WVfSg/


3
いいえ、これは1.4.3壊れています。最小1.4.4が明示的に必要です。
クレセントフレッシュ

ありがとう。それがまさに私が探していたものです。私は以前1.4.3でそれを試しました、そしてそれほど遠くに行きませんでした。jsfiddleデモも役に立ちました。
Shawn Chin

2
@Isc:非常に迷惑である一つのことは、「デシリアライズ」値でjQueryの試みは属性で見つかっている(つまり、マスターから!jQuery.isNaN( data ) ? parseFloat( data ) : ...)。私の属性には、製品のシリアル番号がありました。たとえば、data-serial="00071134"jQueryが数値に変化した71134ため、エレガントではないものに戻す必要がありました.attr('data-serial')(オプションではありません)。私はSOで同様のフラストレーションを指摘した質問を見てきました.data()、それを掘り出そうとします...
Crescent Fresh

@CrescentFresh:良い点。間違いなく私は注意する必要があります。私のソリューション(gist.github.com/701652)では、jQuery <1.4.3の場合、node.attributesの解析にフォールバックします。この問題を念頭に置いて、おそらく手動で属性を解析することに固執する必要があります。
Shawn Chin

7
は、$.data()を使用して保存したものも返します$.data(key, value)。何かが実際にマークアップにdata- *属性として格納されているかどうかを本当に確認したい場合は、この方法が最良の選択ではない可能性があります。
フィリップウォルトン

81

ソリューションは難しくないので、純粋なJavaScriptソリューションも提供する必要があります。

var a = [].filter.call(el.attributes, function(at) { return /^data-/.test(at.name); });

これにより、属性オブジェクトの配列が得られます。 nameおよびvalueプロパティを:

if (a.length) {
    var firstAttributeName = a[0].name;
    var firstAttributeValue = a[0].value;
}

編集:さらに一歩進めるために、属性を反復してデータオブジェクトにデータを入力することにより、辞書を取得できます。

var data = {};
[].forEach.call(el.attributes, function(attr) {
    if (/^data-/.test(attr.name)) {
        var camelCaseName = attr.name.substr(5).replace(/-(.)/g, function ($0, $1) {
            return $1.toUpperCase();
        });
        data[camelCaseName] = attr.value;
    }
});

次に、たとえばの値にアクセスできます。 data-my-value="2"ようdata.myValue

jsfiddle.net/3KFYf/33

編集:オブジェクトからプログラムで要素のデータ属性を設定したい場合は、次のことができます。

Object.keys(data).forEach(function(key) {
    var attrName = "data-" + key.replace(/[A-Z]/g, function($0) {
        return "-" + $0.toLowerCase();
    });
    el.setAttribute(attrName, data[key]);
});

jsfiddle.net/3KFYf/34

編集: babelまたはTypeScriptを使用している場合、またはes6ブラウザーのみをコーディングしている場合、これはes6矢印関数を使用し、コードを少し短くするのに最適な場所です。

var a = [].filter.call(el.attributes, at => /^data-/.test(at.name));

いい答えだ!最初の行は-jQueryのように文字を置き換えませんが、編集された回答は置き換えます。
Timo Huovinen、2014

@ gilly3 jsfiddleが動作していないようです。見ていただけますか?
Ethan

1
@イーサン-修正。知らせてくれてありがとうございます。私はjsbeautifier.orgのbeautify.jsを使用してJSONをきれいに出力していました。どうやらそのリンクは今壊れています。以来、しかし、それはやり過ぎだったJSON.stringify()。JSONを内蔵書式た
gilly3

@ gilly3素晴らしい、あなたのルーチンはすべてをフェッチするのに最適です。特定のキーのフェッチデータを追加したり、キーの変更されたデータを更新したりするのは簡単ですか?共有できればいいですね。
イーサン

@イーサン-単一の値を取得するために、それを考えすぎないでください el.getAttribute("data-foo")。オブジェクトに基づいてデータ属性を設定する方法を示すために、回答を更新しました。
gilly3、2015

22

ここを見てください

ブラウザーがHTML5 JavaScript APIもサポートしている場合は、次の方法でデータを取得できます。

var attributes = element.dataset

または

var cat = element.dataset.cat

ああ、でも私も読んだ:

残念ながら、新しいデータセットのプロパティはまだ、任意のブラウザで実装されていないので、その間にそれを使用するのがベストだgetAttributesetAttribute以前示されたように。

2010年5月からです。


とにかくjQueryを使用している場合は、customdataプラグインを確認することをお勧めします。私はそれを使った経験はありません。



Felixに感謝します。customdataに遭遇しました。残念ながら、それは私が必要とすることを行いません-つまり、キーが事前に知られていない場合、すべてのデータを取得します。
Shawn Chin

@lsc:ドキュメンテーションはそれ$("#my").customdata()があなたに与えるべきであると言います{method: "delete", remote: "true"}...それでそれはうまくいくはずです。
Felix Kling、2010年

別のjQueryプラグインを使用するのはやり過ぎのようですが、カスタムデータのソースを確認することで、自分のソリューションを修正できました。回答を受け入れ、Qを作業関数で更新します。
Shawn Chin

1
@lsc:まったく問題ありませんが、組み込みソリューションは常に優先されるはずです。残念ながら、私は最新のjQuery開発に最新の状態ではありません;)なぜ誰かが私に投票したのか疑問に思っています...
Felix Kling

5

上記のように、最近のブラウザーにHTMLElement.dataset APIがあります。
このAPIはDOMStringMapを提供し、data-*属性のリストを取得するには、次のようにします。

var dataset = el.dataset; // as you asked in the question

次のdata-ようなプロパティのキー名で配列を取得することもできます

var data = Object.keys(el.dataset);

またはその値をマッピングします

Object.keys(el.dataset).map(function(key){ return el.dataset[key];});
// or the ES6 way: Object.keys(el.dataset).map(key=>{ return el.dataset[key];});

以前と同じように、要素のすべての属性をフィルタリングする必要なく、これらを反復して使用できます。


3

またはgilly3の優れた答えをjQueryメソッドに変換します。

$.fn.info = function () {
    var data = {};
    [].forEach.call(this.get(0).attributes, function (attr) {
        if (/^data-/.test(attr.name)) {
            var camelCaseName = attr.name.substr(5).replace(/-(.)/g, function ($0, $1) {
                return $1.toUpperCase();
            });
            data[camelCaseName] = attr.value;
        }
    });
    return data;
}

使用:$('.foo').info();


2

データセット属性を介してデータを取得する必要があります

var data = element.dataset;

データセットは、データ属性を取得するための便利なツールです


IIRCは、this.datasetまだすべてのブラウザで動作するわけではありません。ただし、この機能を提供するjqueryプラグインがあります。
Shawn Chin

1

他のオブジェクトと同様にデータ属性を反復処理してキーと値を取得できます。これを行う方法は$.each次のとおりです。

    $.each($('#myEl').data(), function(key, value) {
        console.log(key);
        console.log(value);
    });

1

私はネストされたそれぞれを使用しています -私にとってはこれが最も簡単な解決策です(「値を使って何をするかを制御/変更するのは簡単です-私の例では出力データ属性としてul-list)(Jqueryコード)

var model = $(".model");

var ul = $("<ul>").appendTo("body");

$(model).each(function(index, item) {
  ul.append($(document.createElement("li")).text($(this).text()));
  $.each($(this).data(), function(key, value) {
    ul.append($(document.createElement("strong")).text(key + ": " + value));
    ul.append($(document.createElement("br")));
  }); //inner each
  ul.append($(document.createElement("hr")));
}); // outer each

/*print html*/
var htmlString = $("ul").html();
$("code").text(htmlString);
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/prism.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/themes/prism-okaidia.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 id="demo"></h1>

<ul>
  <li class="model" data-price="45$" data-location="Italy" data-id="1234">Model 1</li>
  <li class="model" data-price="75$" data-location="Israel" data-id="4321">Model 2</li> 
  <li class="model" data-price="99$" data-location="France" data-id="1212">Model 3</li> 
</ul>

<pre>
<code class="language-html">
  
</code>
</pre>

<h2>Generate list by code</h2>
<br>

コードペン:https ://codepen.io/ezra_siton/pen/GRgRwNw?editors=1111


0

すべてのデータ属性を見つける1つの方法は、を使用することelement.attributesです。を使用すると.attributes、すべての要素属性をループして、文字列「data-」を含むアイテムを除外できます。

let element = document.getElementById("element");

function getDataAttributes(element){
    let elementAttributes = {},
        i = 0;

    while(i < element.attributes.length){
        if(element.attributes[i].name.includes("data-")){
            elementAttributes[element.attributes[i].name] = element.attributes[i].value
        }
        i++;
    }

    return elementAttributes;

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.