[javascript] Get list of data-* attributes using javascript / jQuery

Given an arbitrary HTML element with zero or more data-* attributes, how can one retrieve a list of key-value pairs for the data.

E.g. given this:

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

I would like to be able to programmatically retrieve this:

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

Using jQuery (v1.4.3), accessing the individual bits of data using $.data() is simple if the keys are known in advance, but it is not obvious how one can do so with arbitrary sets of data.

I'm looking for a 'simple' jQuery solution if one exists, but would not mind a lower level approach otherwise. I had a go at trying to to parse $('#prod').attributes but my lack of javascript-fu is letting me down.

update

customdata does what I need. However, including a jQuery plugin just for a fraction of its functionality seemed like an overkill.

Eyeballing the source helped me fix my own code (and improved my javascript-fu).

Here's the solution I came up with:

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

As demonstrated in the accepted answer, the solution is trivial with jQuery (>=1.4.4). $('#prod').data() would return the required data dict.

This question is related to javascript jquery html attributes

The answer is


Have a look here:

If the browser also supports the HTML5 JavaScript API, you should be able to get the data with:

var attributes = element.dataset

or

var cat = element.dataset.cat

Oh, but I also read:

Unfortunately, the new dataset property has not yet been implemented in any browser, so in the meantime it’s best to use getAttribute and setAttribute as demonstrated earlier.

It is from May 2010.


If you use jQuery anyway, you might want to have a look at the customdata plugin. I have no experience with it though.


One way of finding all data attributes is using element.attributes. Using .attributes, you can loop through all of the element attributes, filtering out the items which include the string "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;

}

You can just iterate over the data attributes like any other object to get keys and values, here's how to do it with $.each:

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

You should be get the data through the dataset attributes

var data = element.dataset;

dataset is useful tool for get data-attribute


or convert gilly3's excellent answer to a jQuery method:

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

Using: $('.foo').info();


you could access the data using $('#prod')[0].dataset


As mentioned above modern browsers have the The HTMLElement.dataset API.
That API gives you a DOMStringMap, and you can retrieve the list of data-* attributes simply doing:

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

you can also retrieve a array with the data- property's key names like

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

or map its values by

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

and like this you can iterate those and use them without the need of filtering between all attributes of the element like we needed to do before.


I use nested each - for me this is the easiest solution (Easy to control/change "what you do with the values - in my example output data-attributes as ul-list) (Jquery Code)

_x000D_
_x000D_
var model = $(".model");_x000D_
_x000D_
var ul = $("<ul>").appendTo("body");_x000D_
_x000D_
$(model).each(function(index, item) {_x000D_
  ul.append($(document.createElement("li")).text($(this).text()));_x000D_
  $.each($(this).data(), function(key, value) {_x000D_
    ul.append($(document.createElement("strong")).text(key + ": " + value));_x000D_
    ul.append($(document.createElement("br")));_x000D_
  }); //inner each_x000D_
  ul.append($(document.createElement("hr")));_x000D_
}); // outer each_x000D_
_x000D_
/*print html*/_x000D_
var htmlString = $("ul").html();_x000D_
$("code").text(htmlString);
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/prism.min.js"></script>_x000D_
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/themes/prism-okaidia.min.css" rel="stylesheet"/>_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>_x000D_
<h1 id="demo"></h1>_x000D_
_x000D_
<ul>_x000D_
  <li class="model" data-price="45$" data-location="Italy" data-id="1234">Model 1</li>_x000D_
  <li class="model" data-price="75$" data-location="Israel" data-id="4321">Model 2</li> _x000D_
  <li class="model" data-price="99$" data-location="France" data-id="1212">Model 3</li> _x000D_
</ul>_x000D_
_x000D_
<pre>_x000D_
<code class="language-html">_x000D_
  _x000D_
</code>_x000D_
</pre>_x000D_
_x000D_
<h2>Generate list by code</h2>_x000D_
<br>
_x000D_
_x000D_
_x000D_

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


A pure JavaScript solution ought to be offered as well, as the solution is not difficult:

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

This gives an array of attribute objects, which have name and value properties:

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

Edit: To take it a step further, you can get a dictionary by iterating the attributes and populating a data object:

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

You could then access the value of, for example, data-my-value="2" as data.myValue;

jsfiddle.net/3KFYf/33

Edit: If you wanted to set data attributes on your element programmatically from an object, you could:

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: If you are using babel or TypeScript, or coding only for es6 browsers, this is a nice place to use es6 arrow functions, and shorten the code a bit:

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

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to attributes

Get the name of a pandas DataFrame What is initial scale, user-scalable, minimum-scale, maximum-scale attribute in meta tag? AttributeError: can't set attribute in python How can I disable selected attribute from select2() dropdown Jquery? How do I pass multiple attributes into an Angular.js attribute directive? AngularJS - Attribute directive input value change Are complex expressions possible in ng-hide / ng-show? Get all attributes of an element using jQuery Removing html5 required attribute with jQuery Set attribute without value