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
source to share
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
source to share
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 .
source to share