Find all data attributes in one element

Does anyone know of a quick and efficient way to grab all data attributes from a single element? I understand that jQuerys.data () will do exactly that, however it won't give me the data attributes set using .attr () UNLESS. First I select the data attribute using .data (); Also, you cannot select items by data attributes that were added using .data (), which seems silly.

Html

<div data-foo="bar"></div>

      

Javascript

$("div").data();
//returns {foo:bar} good :)

$("div").attr("data-hello","world");
$("div").data()
//returns {foo:bar} no good :(

$("div[data-hello]");
//returns the div, all good :)

$("div").data("find","me");
$("div[data-find]");
//returns nothing, very bad

      

Hope this explains

+3


source to share


2 answers


You can use dataset property in modern browsers (IE11 + only), but you can improve the solution to use . attributes to support older browsers

var $in = $('input'),
    input = $in[0], //here input is a dom element reference
    dataMap = input.dataset;
//if dataset is not supported
if (typeof dataMap == 'undefined') {
    dataMap = {};
    $.each(input.attributes, function (key, attr) {
        var match = attr.name.match(/^data-(.+)/);
        if (match) {
            dataMap[match[0]] = attr.value;
        }
    })
}
$.each(dataMap, function (key, value) {
    console.log(key, value)
})

      



Demo: Fiddle

+6


source


Different versions of Internet Explorer support different features that are relevant to this issue. In version 11, support was added dataset

that returns a DOMStringMap of data attribute names (minus the "data-" part) and their corresponding values.

In versions 9 and 10, we can use Array.prototype.slice to convert a well-maintained collection attributes

to an array, which can then be reduced to an object like DOMStringMap.

We can combine both of these approaches into a single function that takes an element as its argument and returns an object like this: {name: "pat", "age": 23} for all data attributes:



function getDataAttributes ( el ) {
    return el.dataset || [].slice.call( el.attributes ).reduce(function ( o, a ) {
        return /^data-/.test( a.name ) && ( o[ a.name.substr( 5 ) ] = a.value ), o;
    }, {} );
}

      

If you need Internet Explorer 8 or below support, you can still use the above approaches and just polyfill Array.prototype.reduce .

+5


source







All Articles