使用 javascript / jQuery 获取 data-* 属性列表
Posted
技术标签:
【中文标题】使用 javascript / jQuery 获取 data-* 属性列表【英文标题】:Get list of data-* attributes using javascript / jQuery 【发布时间】:2011-05-10 09:04:31 【问题描述】:给定一个具有零个或多个data-*
属性的任意 html 元素,如何检索数据的键值对列表。
例如鉴于此:
<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()
访问数据的各个位很简单,但对于任意数据集如何做到这一点并不明显。
我正在寻找一种“简单”的 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;
更新 2
正如接受的答案所示,使用 jQuery (>=1.4.4) 的解决方案很简单。 $('#prod').data()
将返回所需的数据字典。
【问题讨论】:
Addresing "update 2" 注意 jquery data() 使用一些内部缓存并且 data(key, value) 不会传播到 DOM,这可能会引起很多麻烦。同样由于 jquery 3 data() 将属性 data-some-thing="test" 转换为 someThing: "test" 【参考方案1】:实际上,如果您使用 jQuery,从版本 1.4.3 1.4.4 开始(因为下面的 cmets 中提到的错误),data-*
属性通过 @ 支持987654321@:
截至 jQuery 1.4.3 HTML 5
data-
属性会自动 拉入到 jQuery 的数据对象中。请注意,字符串保持不变 而 JavaScript 值被转换 到它们的相关值(这 包括布尔值、数字、对象、 数组和空)。
data-
属性被拉到第一个 访问数据属性的时间和 然后不再被访问或变异 (然后存储所有数据值 在 jQuery 内部)。
jQuery.fn.data
函数会将对象内的所有data-
属性作为键值对返回,其中键是data-
之后的属性名称部分,值是该属性之后的值按照上述规则进行转换。
如果这不能说服您,我还创建了一个简单的演示:http://jsfiddle.net/yijiang/WVfSg/
【讨论】:
不,这是broken in 1.4.3。明确要求至少 1.4.4。 谢谢。这正是我一直在寻找的。我之前用 1.4.3 尝试过,但并没有走得太远。 jsfiddle 演示也有帮助。 @Isc:一件非常烦人的事情是 jQuery 试图“反序列化”属性中的值(即from master:!jQuery.isNaN( data ) ? parseFloat( data ) : ...
)。我的属性中有产品序列号,例如data-serial="00071134"
,jQuery 将其转换为数字71134
,迫使我恢复到不太优雅的.attr('data-serial')
(在您的情况下不是一个选项)。我已经看到关于 SO 的问题在.data()
上表达了类似的挫败感,我会尝试挖掘一个......
@CrescentFresh:好点。绝对是我应该注意的事情。在我的解决方案(gist.github.com/701652)中,当 jQuery
请记住,$.data()
还会返回您使用 $.data(key, value)
存储的任何内容。如果您确实想检查某些内容是否作为 data-* 属性实际存储在标记中,则此方法可能不是最佳选择。【参考方案2】:
还应该提供纯 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
访问;
jsfiddle.net/3KFYf/33
编辑:如果您想通过对象以编程方式设置元素的数据属性,您可以:
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
编辑:如果你正在使用 babel 或 TypeScript,或者只为 es6 浏览器编码,这是一个使用 es6 箭头函数的好地方,并稍微缩短代码:
var a = [].filter.call(el.attributes, at => /^data-/.test(at.name));
【讨论】:
好答案!第一行不会像 jQuery 那样替换-
字符,但编辑后的答案会。
@gilly3 您的 jsfiddle 似乎不起作用。可以看看吗?
@Ethan - 已修复。谢谢你让我知道。我一直在使用来自 jsbeautifier.org 的 beautify.js 来漂亮地打印 JSON。显然,该链接现在已断开。但是,因为JSON.stringify()
内置了 JSON 格式,所以这太过分了。
@gilly3 太棒了,你的例程非常适合获取所有内容。为给定键添加获取数据以及更新键的修改数据是否容易?如果你能分享,那就太好了。
@Ethan - 要获得单个值,请不要想太多:el.getAttribute("data-foo")
。我已经更新了我的答案,以展示如何根据对象设置数据属性。【参考方案3】:
Have a look here:
如果浏览器也支持 HTML5 JavaScript API,您应该能够通过以下方式获取数据:
var attributes = element.dataset
或
var cat = element.dataset.cat
哦,但我也读到了:
很遗憾,新的数据集属性尚未在任何浏览器中实现,因此最好同时使用
getAttribute
和setAttribute
,如前所述。
从 2010 年 5 月开始。
如果你仍然使用 jQuery,你可能想看看customdata 插件。不过我没有这方面的经验。
【讨论】:
也感兴趣,来自 ppk:quirksmode.org/dom/w3c_core.html#attributes 谢谢菲利克斯。我遇到了customdata。不幸的是,它不能满足我的需要——即在事先不知道密钥的情况下获取所有数据。 @lsc:文档说$("#my").customdata()
应该给你method: "delete", remote: "true"
...所以它应该可以工作。
使用单独的 jQuery 插件似乎有点过头了,但是查看 customdata 的源代码帮助我修复了自己的解决方案!将接受您的回答并使用工作功能更新 Q。
@lsc:完全没问题,内置解决方案应该始终是 imo 的首选。不幸的是,我不了解最新的 jQuery 开发;)只是想知道为什么有人投票反对我......【参考方案4】:
如上所述,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 的所有属性之间进行过滤。
【讨论】:
【参考方案5】:或将gilly3
的出色答案转换为 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;
使用:$('.foo').info()
;
【讨论】:
【参考方案6】:您应该通过数据集属性获取数据
var data = element.dataset;
dataset 是获取数据属性的有用工具
【讨论】:
IIRC,this.dataset
尚不适用于所有浏览器。然而,有一个 jquery plugin 提供了这个功能。【参考方案7】:
您可以像任何其他对象一样遍历数据属性以获取键和值,以下是使用 $.each
的方法:
$.each($('#myEl').data(), function(key, value)
console.log(key);
console.log(value);
);
【讨论】:
【参考方案8】:我使用嵌套的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】:查找所有数据属性的一种方法是使用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;
【讨论】:
【参考方案10】:您可以使用 $('#prod')[0].dataset 访问数据
【讨论】:
这个问题的许多答案已经描述了使用dataset
属性。以上是关于使用 javascript / jQuery 获取 data-* 属性列表的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 javascript / jQuery 获取数据 ajax api 数组?
使用 jQuery / JavaScript 从超链接获取完整 URL