使用 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); );

这给出了一个属性对象数组,它们具有namevalue 属性:

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

哦,但我也读到了:

很遗憾,新的数据集属性尚未在任何浏览器中实现,因此最好同时使用getAttributesetAttribute,如前所述。

从 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

使用jquery和javascript获取标签名称[重复]

使用 Jquery/Javascript 根据按钮单击获取表行值

JavaScript 使用jQuery获取表单输入字段

通过获取 .attr 使用 JavaScript/jquery 播放/暂停音频文件