【问题标题】:jQuery's data() attribute does not update when element data changes元素数据更改时,jQuery data() 属性不会更新
【发布时间】:2014-03-02 12:30:32
【问题描述】:

我想使用 jQuery 的data() api 来检索元素的所有数据属性。但是这个 api 的缓存特性真的很烦人。有时我需要在 javascript 中更改元素的一些数据属性,但 data() api 总是返回每个数据属性的初始值。所以我必须使用attr() 来访问元素的每个数据属性以获取其最新值。有什么办法可以克服这个缓存问题,让data() 每次调用它时总是返回最新值?

【问题讨论】:

  • 这不是缓存的东西,data() 在内部存储数据并且不会更改数据属性,如果您出于某种原因必须更改属性,您应该使用attr(),但如果您'重新使用data() 来设置和获取数据,这应该不是问题,因为您将获得正确的数据。
  • “有时我需要在 javascript 中更改元素的一些数据属性” - 为什么?如果您需要在页面加载后针对元素存储数据,您可以使用.data('key','value')。这不会将数据存储为属性,但那又如何?
  • @nnnnnn 每种客户端模板语言都会构建 DOM,其中可能包含数据属性,而 jQuery 很可能不会这样做。

标签: javascript jquery html custom-data-attribute


【解决方案1】:

简短的回答是:不要使用 jQuery .data() 来动态设置数据属性,除非你能保证数据属性总是由 jQuery 设置

以下任一解决方案都可以:

  • 改用原版JS .getAttribute()
  • 改用 jQuery .attr()

这是relevant part from the jQuery documentation(我认为这并没有真正突出这可能会让 jQuery 用户感到惊讶):

data-属性在第一次访问数据属性时被拉取,然后不再被访问或改变(所有数据值都存储在jQuery内部)。

关于为什么你可能使用 jQuery 来设置属性:许多客户端模板语言构建 DOM,包括数据属性。

给定动态构建的 HTML(如 DevTools 所示:

<form data-test="300" ...

DOM API 说实话:

 document.querySelector('form').getAttribute('data-test');

JQuery 返回一个过时的先前值(在本例中为 19000):

 $('form').data('test');

jQuery attr 返回当前值:

 $('form').attr('data-amount');

Vanilla JS getAttribute() 返回当前值:

 document.querySelector('form').getAttribute('data-amount');

【讨论】:

  • 很好的答案,先生。谢谢!
  • 绝对正确的答案。我为这个问题困扰了几个小时。
【解决方案2】:

你也可以在更新数据属性后使用jQuery的.removeData()方法来重置它的缓存。

例如:

> document.querySelector('.sub-panels')
<div class=​"sub-panels">​…​</div>​

> document.querySelector('.sub-panels').setAttribute('data-test', 300);
undefined

> document.querySelector('.sub-panels')
<div class=​"sub-panels" data-test="300">​…​</div>​

> $('.sub-panels').data('test')
300

> document.querySelector('.sub-panels').setAttribute('data-test', 400);
undefined

> $('.sub-panels').data('test')
300

> $('.sub-panels').removeData();
[div.sub-panels, prevObject: jQuery.fn.init(1), context: document, selector: ".sub-panels"]

> $('.sub-panels').data('test')
400

【讨论】:

    【解决方案3】:

    如果你没有绑定 jQuery,你可以使用attributes 来遍历所有属性。那么它们是否动态添加都没有关系。

    const p = document.getElementById('test')
    p.setAttribute('data-test', 300)
    
    for (const attr of p.attributes) {
      // possibly filter with attr.name.startsWith('data-')
      console.log(`${attr.name}: ${attr.value} (is data-attr: ${attr.name.startsWith('data-')})`)
    }
    
    p.setAttribute('data-new', 400)
    
    for (const attr of p.attributes) {
      // possibly filter with attr.name.startsWith('data-')
      console.log(`${attr.name}: ${attr.value} (is data-attr: ${attr.name.startsWith('data-')})`)
    }
    &lt;p id="test"&gt;Test&lt;/p&gt;

    【讨论】:

      猜你喜欢
      • 2014-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-07
      • 2019-05-18
      • 1970-01-01
      • 2020-04-15
      • 1970-01-01
      相关资源
      最近更新 更多