Get list of data - * attributes using javascript / jQuery

Biorąc pod uwagę dowolny element HTML z zerowymi lub więcej atrybutami data-*, Jak można pobrać listę par klucz-wartość dla danych.

Np. biorąc pod uwagę to:

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

Chciałbym móc programowo pobrać to:

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

Korzystanie z jQuery (v1.4.3), dostęp do poszczególnych bitów danych za pomocą $.data() jest prosty, jeśli klucze są znane z góry, ale nie jest oczywiste, jak można to zrobić z dowolnymi zestawami danych.

Szukam "proste" rozwiązanie jQuery, jeśli istnieje, ale nie przeszkadza niższego poziomu podejście inaczej. Próbowałem parsować $('#prod').attributes, ale mój brak javascript-fu mnie zawodzi.

Update

Customdata robi to, czego potrzebuję. Jednak włączenie wtyczki jQuery tylko dla ułamka jego funkcjonalności wydawało się przesadą.

Oczyszczenie źródła pomogło mi naprawić mój własny kod (i poprawiło mój javascript-fu).

Oto rozwiązanie, które wymyśliłem z:

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;
}

Update 2

Jak wykazano w zaakceptowanej odpowiedzi, rozwiązanie jest trywialne z jQuery (>=1.4.4). $('#prod').data() zwróci wymagane dane dict.

Author: Vertexwahn, 2010-11-15

10 answers

Właściwie, jeśli pracujesz z jQuery, od wersji 1.4.3 1.4.4 (z powodu błędu opisanego w komentarzach poniżej) atrybuty data-* są obsługiwane przez .data():

Od jQuery 1.4.3 HTML 5 data- atrybuty będą automatycznie ściągnięty do obiektu danych jQuery.

Zauważ, że ciągi są nienaruszone podczas konwersji wartości JavaScript do ich powiązanej wartości (to zawiera wartości logiczne, liczby, obiekty, tablice, I null). The data- atrybuty są wyciągane w pierwszym czas dostępu do właściwości danych i wtedy nie są już dostępne lub zmutowane (wszystkie wartości danych są następnie zapisywane wewnętrznie w jQuery).

Funkcja jQuery.fn.data zwróci wszystkie atrybuty data- wewnątrz obiektu jako pary klucz-wartość, przy czym klucz jest częścią nazwy atrybutu po data-, a wartość jest wartością tego atrybutu po przekonwertowaniu zgodnie z zasadami podanymi powyżej.

I ' ve stworzyłem również proste demo, jeśli to cię nie przekonuje: http://jsfiddle.net/yijiang/WVfSg/

 97
Author: Yi Jiang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-31 13:37:22

Należy również zaoferować czyste rozwiązanie JavaScript, ponieważ rozwiązanie nie jest trudne:

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

To daje tablicę obiektów atrybutów, które mają właściwości name i value:

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

Edit: aby pójść o krok dalej, możesz uzyskać słownik poprzez iterację atrybutów i wypełnienie obiektu danych:

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;
    }
});

Możesz wtedy uzyskać dostęp do wartości, na przykład, data-my-value="2" jako data.myValue;

Jsfiddle.net/3KFYf/33

Edit: jeśli chcesz ustawić atrybuty danych na swoim elemencie programowo z obiektu, możesz:

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

EDIT: Jeśli używasz babel lub TypeScript, lub kodujesz tylko dla przeglądarek es6, jest to dobre miejsce do korzystania z funkcji strzałek ES6 i skrócenia kodu trochę:

var a = [].filter.call(el.attributes, at => /^data-/.test(at.name));
 87
Author: gilly3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-29 19:03:18

Zobacz tutaj :

Jeśli przeglądarka obsługuje również HTML5 JavaScript API, powinieneś być w stanie uzyskać dane z:

var attributes = element.dataset

Lub

var cat = element.dataset.cat
[[4]} Och, ale też czytałem:

Niestety, Nowa właściwość dataset nie została jeszcze zaimplementowana w żadnej przeglądarce, więc w międzyczasie najlepiej używać getAttribute i setAttribute Jak pokazano wcześniej.

Jest od maja 2010 roku.


Jeśli i tak używasz jQuery, możesz rzucić okiem na customdata plugin. Nie mam z tym doświadczenia.

 23
Author: Felix Kling,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-15 17:23:07

Jak wspomniano powyżej nowoczesne przeglądarki mają HTMLElement.zbiór danych API.
Ten API daje Ci DOMStringMap , i możesz pobrać listę data-* atrybutów po prostu wykonując:

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

Można również pobrać tablicę z nazwami kluczy właściwości data-, takimi jak

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

Lub odwzorować jego wartości przez

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];});

I w ten sposób możesz je iterować i używać bez potrzeby filtrowania pomiędzy wszystkimi atrybutami elementu tak jak musieliśmy zrobić przed .

 6
Author: Sergio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:04

Lub przekonwertować gilly3 doskonałą odpowiedź na metodę 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;
}

Za pomocą: $('.foo').info();

 3
Author: PHPst,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-13 03:35:14

Dane powinny być pobierane przez atrybuty zestawu danych

var data = element.dataset;

Dataset jest użytecznym narzędziem dla get data-atrybut

 2
Author: lychi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-01 14:28:42

Możesz po prostu iterować nad atrybutami danych, jak każdy inny obiekt, aby uzyskać klucze i wartości, oto jak to zrobić z $.each:

    $.each($('#myEl').data(), function(key, value) {
        console.log(key);
        console.log(value);
    });
 1
Author: Andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-09 14:22:33

Używam zagnieżdżonych KAŻDEGO - dla mnie jest to najprostsze rozwiązanie (łatwe do kontrolowania/zmiany "co robisz z wartościami-w moim przykładzie dane wyjściowe-atrybuty jako ul-list) (Kod 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>

Codepen: https://codepen.io/ezra_siton/pen/GRgRwNw?editors=1111

 1
Author: Ezra Siton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-03 03:39:00

Jednym ze sposobów znajdowania wszystkich atrybutów danych jest użycie element.attributes. Używając .attributes, możesz przeszukiwać wszystkie atrybuty elementu, filtrując elementy zawierające łańcuch " 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;

}
 0
Author: Jmorel88,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-08 20:49:28

Możesz uzyskać dostęp do danych za pomocą $('#prod') [0].dataset

 -1
Author: miftah al rasyid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-13 08:28:06