HTML 5已经不是什么新鲜事物了(它于2014年底首次亮相),但它的功能并不像HTML中更古老的领域那样广为人知。有时这是由于缺乏浏览器支持,有时是开发人员不必要地坚持jQuery,有时是团队试图维护一个在HTML 5之前的大型,繁琐的网站。对于我们这些可以自由地接受HTML 5所提供的一切的人来说,有很多力量可以拥有。数据属性是 HTML 5 中更强大的补充之一。
数据属性
在我们的 HTML 中使用属性是很常见的。我们可以使用class
属性将 CSS 类应用于元素,写入style
属性以重写、测试或调试样式表,或者添加布尔属性(如窗体中的required和input
元素)。数据属性和属性之间的最大区别在于,数据属性是由开发人员定义的,而不是从一开始就内置于HTML中。数据属性是我们可以设置的钩子,为我们的HTML提供与CSS和JavaScript通信的新方式。
创建数据属性
添加数据属性非常简单。任何 HTML 元素都可以将任意数量的数据属性添加到其开始标记中。我们只需在元素的开始标记中键入属性的名称data-
,然后键入我们属性的名称,以及我们已经在使用的任何其他属性。
例如,让我们创建一个名为“徽章”的数据属性,并使用它来将数字附加到元素p
。
<p data-badges="3">This is a paragraph element.</p>
CSS 中的数据属性
有两种方法可以轻松地从样式表中查看数据属性。第一个是属性选择器,第二个是attr()
函数。
在 CSS 中使用属性选择器
我们可以在编写 CSS 规则时定位 HTML 属性。这样做的常见用途是通过为input[type="checkbox"]
类似的东西编写规则来选择某些类型的输入元素。实际上,任何属性都可以成为我们CSS规则中的选择器。使用数据属性以这种方式应用样式可以通过减少帮助程序类来使样式表组织更好;我们可以针对数据属性来应用所需的样式并培养更具语义性的样式表,而不是创建任意类(如 .one-badge
、.two-badges
、.three-badges
) 并将它们手动附加到元素。当其他人(或我们未来的自己)进入阅读我们的CSS时,我们的意图会更加清晰。
例如,如果我们想使用附加的“徽章”数据来设置段落样式,我们可以在样式表中使用方括号[ ]
检查该 data 属性。
p[data-badges=“1”] {
background: orange;
}
p[data-badges=“2”] {
background: gold;
}
p[data-badges=“3”] {
background: lime;
}
这使得我们更改background
值的逻辑来自哪里比在元素p
上不透明地拍打帮助器类更明显。
在 CSS 中使用attr()
函数
attr()
函数允许我们将数据从HTML文档拉入CSS样式表。这使我们能够进一步远离手动应用属性选择器提供的样式,更接近于将数据属性视为变量。
CSS 规则应用于与包含这些规则的选择器匹配的 HTML 元素。attr()
函数允许我们从正在选择的元素和样式中获取数据。为此,请使用attr()
所需数据属性的名称并将其作为参数传递。
例如,让我们在段落元素后面显示数据属性的值。我们只需要在样式表中添加一个 CSS 规则。
p::after {
content: attr(data-badges);
}
脚本中的数据属性
JavaScript 允许我们完成从手动将数据附加到元素的过渡。数据属性是为 HTML 元素提供额外信息的好方法,但是使用 JavaScript 从这些属性中获取和设置数据才是真正使此功能有用的原因。就像将它们写入 HTML 并使用 CSS 定位它们一样,HTML 5 使得在 JavaScript 中处理数据属性变得非常容易。
在脚本中读取 HTML 数据属性
HTML 元素的所有数据属性均可在Element.dataset
上访问。dataset
对象是一个 DOMStringMap,其中每个数据属性都作为子属性附加。只需向下钻取dataset
并按名称请求您的属性即可。
// Start by grabbing our paragraph element
var element = document.querySelector('p');
// Now we can check the value of our data attribute
var badges = element.dataset.badges;
console.log('Badges data attribute value:', badges);
在脚本中设置 HTML 数据属性
当我们想要为数据属性设置新值时,我们可以使用与设置任何内置 HTML 属性相同的 JavaScript 函数:setAttribute()
。
// We can set our data attribute to 4
element.setAttribute('data-badges', '4');
请注意,此处我们在属性名称之前包含,因为此函数不特定于数据属性。data-
支持和辅助功能说明
与往常一样,在生产中使用 Web 功能之前,请务必检查这些功能的广泛支持程度。HTML数据属性享有相当广泛的支持,但有一个警告:旧版本的IE浏览器不支持Element.dataset
。为了迎合该用户群(撰写本文时占用户的0.34%),您可以按
上面讨论的Element.setAttribute()
方式使用Element.getAttribute()
。只需传递一个参数(您尝试抓取的属性的名称),该属性的值将返回给您。
// We can still read a data attribute's value without dataset
var badges = element.getAttribute('data-badges');
可访问性是一个更大的问题;始终花时间使您的网络创作尽可能广泛地访问。我们需要免费提供网络技术和学习资源,以确保网络作为公共平台的增长和发展。
使用数据属性时的主要可访问性问题是辅助技术可能无法读取它们。对用户重要的信息绝不应仅在数据属性中陈述;请务必在页面上的传统元素中重述任何面向公众的信息。
将所有内容放在一起
让我们将另一个跨 HTML、CSS 和脚本使用数据属性的示例放在一起。让我们从一个空白的 HTML 页面开始。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Data Attributes</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style></style>
</head>
<body>
<script></script>
</body>
</html>
对于此示例,我们将一个简单的工具栏放在一起,其中包含一个用于打开和关闭导航菜单的按钮。让我们将必要的元素放入 .body
<body>
<header>
<h1>Toolbar</h1>
<button id="menu-btn">Menu</button>
</header>
<nav data-active="false">
<ul>
<li>News</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
<script></script>
</body>
请注意,我们在按钮上放置了一个id
属性,以便我们可以在 JavaScript 中放心地选择它,并且我们在nav
元素上放置了一个调用的数据属性active
。
现在,让我们向页面head
添加一小撮 CSS。在以下代码中:
<style>
header {
background: #ccc;
display: flex;
justify-content: space-between;
align-items: center;
}
</style>
我们在这里所做的就是为标题设置一个背景,使其看起来更像一个工具栏,并使用一些弹性规则将header
内部h1
和button
扩展到边缘。
现在让我们考虑一下我们希望按钮做什么。就像永远存在的汉堡包按钮一样,我们只希望它打开和关闭导航菜单。我们将使用此行为来获取数据属性知识进行旋转。
所以现在让我们添加到我们的CSS中:
nav[data-active="false"] {
display: none;
}
nav[data-active="true"] {
display: block;
}
现在,当数据属性active
设置为"true"
时,将显示它,但当它设置为"false"
时,将不显示。将此添加到style
标记中后,nav
元素应该会消失,因为我们已经编写了data-active="false"
。
为了使按钮正常工作,我们将 JavaScript 添加到 HTML body
末尾的script
标记中。让我们编写一个函数来处理切换,然后将其附加到按钮上的单击事件。
// First, grab our nav element
var nav = document.querySelector('nav');
// Then grab our menu button element
var menuButton = document.getElementById('menu-btn');
// Prepare a function to toggle the nav menu
var toggleNav = () => {
// Check the data attribute to see if the menu is currently
// active---notice that the data is a string
var active = (nav.dataset.active === 'true');
active = !active;
nav.setAttribute('data-active', active);
}
// Listen for clicks on the menu button and
// handle clicks with the above toggleNav function
menuButton.addEventListener('click', toggleNav);
如果我们在浏览器中运行示例代码,则该按钮应按预期显示和隐藏导航菜单。关于在JavaScript中读取数据属性的一个注意事项:它们总是以字符串的形式到达。我们可能希望使用parseInt()
将数据解析为整数,将其转换为布尔值,就像我们上面使用 data 属性active
所做的那样,或者以其他方式将数据解析为更有用的类型。请记住,存储在数据属性中的数据始终被 HTML 视为字符串。
㯱
最后一点:使用数据属性不会像处理 JavaScript 对象中的值那样快。数据属性功能强大,在我看来未得到充分利用,但与任何其他技术一样,请记住,数据属性只是工具带上的一个工具,它们应该是构成功能齐全的解决方案的更大方法组合的一部分。尝试使用数据属性在代码中快速移动数据命中!