在 JavaScript 和 CSS 中使用 data-* 属性

当 HTML5 被定义时,其中一项计划是扩展 HTML 中数据的可扩展性,但这些数据不可见。 data-* 属性 允许我们在 HTML 元素上存储额外的信息,而无需使用非语义元素或污染类名。从本质上讲,这就是我们之前使用自定义属性的方式。

这些数据属性可以用多种方式使用,有些是不好的主意,但有些是好的计划。经验法则是,应该可见和可访问的内容不应存储在其中。原因是辅助技术不太可能访问它们,搜索爬虫也不会索引它们。

语法非常简单。假设您有一篇文章,并且您想要存储一些没有视觉表示的额外信息。只需为此使用数据属性即可

...

在 JavaScript 中读取这些属性也非常简单。您可以使用 getAttribute 来读取它们,但 HTML5 标准定义了一种更简单的方法:一个 DOMStringMap,您可以通过 dataset 属性读取它

var article = document.querySelector('#electriccars'),
              data = article.dataset;

// data.columns -> "3"
// data.indexnumber -> "12314"
// data.parent -> "cars"

每个属性都是一个字符串(即使您在 HTML 中省略了引号),并且可以读取和写入。在上述情况下,设置 article.dataset.columns = 5 将更改该属性。

现在,由于 data-属性是普通的 HTML 属性,您甚至可以从 CSS 中访问它们。例如,要显示文章上的父级数据,您可以使用 CSS 中的生成内容

article::before {
  content: attr(data-parent);
}

您还可以使用 CSS 中的属性选择器根据数据更改样式

article[data-columns='3']{
  width: 400px;
}
article[data-columns='4']{
  width: 600px;
}

您可以在 此 JSBin 示例 中看到所有这些内容协同工作。

数据属性还可以存储以包含不断变化的信息,例如游戏中的分数。在此处使用 CSS 选择器和 JavaScript 访问,这使您能够构建一些巧妙的效果,而无需编写自己的显示例程。有关使用生成内容和 CSS 过渡的示例,请参阅 以下屏幕录像

屏幕录像中显示的代码示例也在 JSBin 上

data-属性的问题

遗憾的是,似乎没有什么东西是如此简单和有用,而不会付出代价。在这种情况下,需要考虑的主要问题是 Internet Explorer 不支持 dataset,但您需要改为使用 getAttribute() 读取它们。另一个问题是 读取 data-属性的性能 与将这些数据存储在 JS 数据仓库中的性能相比很差。使用 dataset 甚至比使用 getAttribute() 读取数据更慢。

也就是说,对于不应显示的内容,它们是一个很好的解决方案,也许我们可以很快将其纳入下一个 IE 版本中。

关于 Chris Heilmann

HTML5 和开放网络的布道者。让我们修复它!

更多 Chris Heilmann 的文章…


11 条评论

  1. Maujor

    本文已翻译成巴西葡萄牙语。
    翻译托管于:Uso do atributo data-* em JavaScript e CSS
    感谢 Chris!

    编辑注:已修复链接

    2012年10月11日 06:46

    1. Robert Nyman

      太好了,谢谢!

      2012年10月11日 09:16

  2. leoman730

    确实如此。我正在等待在生产环境中使用它的黄金时期。感谢这篇文章。

    2012年10月11日 06:59

    1. Robert Nyman

      听起来不错!

      2012年10月11日 09:17

  3. Rafael

    活到老学到老。

    我之前就知道 JS 中的这个方法。由于我几乎一直都在使用 JQuery,所以一直都这样操作
    var xpto = $(this).data(‘xpto’);

    但我不知道可以在 CSS3 中使用数据属性。
    非常感谢,干得好 :)

    2012年10月12日 08:29

    1. Robert Nyman

      很高兴听到!

      2012年10月12日 12:29

  4. Arthur

    你好 :)

    “确实如此。我正在等待在生产环境中使用它的黄金时期。感谢这篇文章。”

    我在生产环境中使用它——http://professionali.ru/。它在 IE8 中也能正常工作,但不仅在 dataset 上存在问题,而且 IE 在更改 data-* 属性时不会重新绘制,因此,我使用了 hack 来强制 IE 重新绘制。

    2012年10月12日 14:00

    1. Robert Nyman

      不错,感谢提示!

      2012年10月14日 05:13

  5. fbender

    为什么 dataset 如此缓慢?为什么它甚至比 get/setAttribute 更慢?它有自己的 API,它应该更快或至少与 get/setAttribute 一样快。它目前的实现方式不会让任何人使用特殊的 API…

    相关说明:Web 内容是 Snappy 关注的内容吗?

    2012年10月16日 06:34

    1. fbender

      参见 Bug 802157 (https://bugzilla.mozilla.org/show_bug.cgi?id=802157)

      2012年10月16日 11:29

  6. Alessandro

    感谢您撰写这篇文章,解释得很好,我真的很喜欢。

    2012年10月17日 03:16

本文的评论已关闭。