给定具有零个或多个data-*
属性的任意HTML元素,如何检索数据的键值对列表。
E.g。鉴于此:
<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()
访问单个数据位很简单,但是如何使用任意数据集进行访问并不明显。< / p>
我正在寻找一个'简单'的jQuery解决方案,如果存在,但不会介意低级别的方法。我试图解析$('#prod').attributes
,但我缺乏javascript-fu让我失望。
customdata做我需要的。但是,包括一个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;
}
如公认的答案所示,使用jQuery(&gt; = 1.4.4)解决方案是微不足道的。 $('#prod').data()
将返回所需的数据字典。
答案 0 :(得分:93)
实际上,如果您正在使用jQuery,那么从版本 1.4.3 1.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/
答案 1 :(得分:77)
也应提供纯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
;
编辑:如果您想以编程方式从对象设置元素的数据属性,您可以:
Object.keys(data).forEach(function(key) {
var attrName = "data-" + key.replace(/[A-Z]/g, function($0) {
return "-" + $0.toLowerCase();
});
el.setAttribute(attrName, data[key]);
});
编辑:如果你使用的是babel或TypeScript,或者只为es6浏览器编码,这是一个使用es6箭头功能的好地方,并且稍微缩短了代码:
var a = [].filter.call(el.attributes, at => /^data-/.test(at.name));
答案 2 :(得分:20)
如果浏览器也支持HTML5 JavaScript API,您应该能够通过以下方式获取数据:
var attributes = element.dataset
或
var cat = element.dataset.cat
哦,但我也读到了:
不幸的是,新的数据集属性尚未在任何浏览器中实现,因此在此期间最好使用
getAttribute
和setAttribute
,如前所示。
从2010年5月开始。
如果您仍然使用jQuery,您可能需要查看customdata插件。我没有经验。
答案 3 :(得分:5)
如上所述modern browsers有The 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];});
并且像这样你可以迭代它们并使用它们,而不需要在元素like we needed to do before的所有属性之间进行过滤。
答案 4 :(得分:3)
或转换undefined
对jQuery方法的出色答案:
gilly3
使用:$.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;
}
;
答案 5 :(得分:2)
答案 6 :(得分:0)
查找所有数据属性的一种方法是使用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;
}
答案 7 :(得分:0)
您可以像访问任何其他对象一样遍历数据属性以获取键和值,这是使用$.each
的方法:
$.each($('#myEl').data(), function(key, value) {
console.log(key);
console.log(value);
});
答案 8 :(得分:0)
我使用嵌套的each-对我来说,这是最简单的解决方案(易于控制/更改“您对值的处理-在我的示例中,输出数据属性为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>
Codepen:https://codepen.io/ezra_siton/pen/GRgRwNw?editors=1111
答案 9 :(得分:-1)
您可以使用 $('#prod')[0].dataset 访问数据