如何将 jQuery .data() 转换为 Vanilla JS?

How to convert jQuery .data() to Vanilla JS?

在将我的一些现有项目从 jQuery 转换为纯 JS 时,我 运行 遇到了 jQuery 的 .data() 实用程序的一些问题。到目前为止,我一直无法找到一种简单的 JS 方法来获取和检查 navGlobal 对象中的所有数据属性。

var navGlobal = document.querySelector('.nav-global');

if (navGlobal !== null &&
    navGlobal.data() &&
    navGlobal.data().account &&
    navGlobal.data().account.accountData &&
    navGlobal.data().account.accountData.address &&
    navGlobal.data().account.accountData.address.zip) {

    // do something

}

我试过的:

最初,我想用 .getAttribute() 和 .hasAttribute() 检查这些数据属性是否存在。但这只会增加混乱——我不确定我将如何使用 vanilla JS 深入到嵌套属性(即 navGlobal.data().account.accountData.address)。 链接 .getAttribute() 并没有真正起作用,因为大多数这些数据属性都附加到 navGlobal 的子元素,而不是 navGlobal 元素本身

最好的方法是什么?

尝试使用 navGlobal.dataset 而不是 navGlobal.data()

此外,如果您想检查嵌套属性是否存在,您可以使用 lodash has 函数来检查嵌套属性。例如

if (has(navGlobal.dataset, 'account.accountData.address.zip')) {
  ....
}

正如安东尼所说,使用 DOMElement.dataset 对象:

var div = document.querySelector('div');
var p = document.querySelector('p');

p.innerHTML = div.dataset.myattribute;
<div data-myattribute="3"></div>
<p></p><!-- Output element -->

jQuery 的数据函数做了两件截然不同的事情:它提供了一个访问数据属性的接口,它提供了一个接口,用于在页面完成后将数据与 DOM 节点相关联加载。关于前一个用例:

递归地收集数据属性看起来像这样。

var navGlobal = document.getElementsByClassName('nav-global')[0];
var data = Object.assign({}, navGlobal.dataset);
var children = navGlobal.getElementsByTagName("*");

Array.from(children).forEach(function (el) {
  Object.assign(data, el.dataset)
})

console.log(data)
<div class="nav-global" data-foo="bar">
  <div data-bar="baz">
    <div data-baz="quux"></div>
  </div>
</div>

如果没有看到更多您的代码就无法更具体,但我建议您采用更好的方法来选择包含 class 名称等数据的元素。

如果您需要嵌套数据结构,并且需要将它们实现为数据属性,则您必须做一些额外的工作才能实现。

如果您查看我的 old jQuery plugin 的源代码,您将看到一种采用平面数据结构并将其转换为嵌套数据结构的简单方法,反之亦然。这大致类似于 PHP & Ruby 在查询字符串中编码嵌套参数的方式。

{
  "account[accountData][address][zip]": "12345"
}

变成

{
  "account": {
    "accountData": {
      "address": {
        "zip": "1234"
      }
    }
  }
}

我的库旨在用于表单输入,但您可以将相同的原则应用于数据属性。

坦率地说,我不明白您为什么不直接在页面上放置 JSON 负载。