HTML的data-*自定义属性是HTML5引入的标准特性,允许开发者给任意HTML元素添加私有的自定义数据,这些数据不会在页面渲染时显示,仅用于脚本交互或数据存储,解决了以往只能通过class、rel等属性间接存储数据的痛点。

data-*属性的设置规则
data-*属性的命名必须遵循固定规范,所有自定义属性都以data-作为前缀,后面跟随至少一个小写字母开头的自定义名称,名称中不能包含大写字母,多个单词之间可以用连字符连接。
基础设置示例
我们可以直接在HTML标签上添加data-*属性,属性值可以是任意字符串,不需要加引号也可以加单引号或双引号,不过建议统一使用双引号符合HTML规范。
<!-- 单个单词的data属性 -->
<div data-id="1001">用户卡片</div>
<!-- 多个单词用连字符连接的data属性 -->
<div data-user-name="张三" data-user-age="25">用户信息</div>
<!-- 存储复杂数据的data属性 -->
<div data-config='{"theme":"dark","lang":"zh"}'>配置容器</div>
通过JavaScript操作data-*属性
设置好data-*属性后,我们可以通过原生的DOM API来读取和修改这些属性,有两种常用的操作方式。
使用getAttribute和setAttribute方法
这是最通用的属性操作方法,直接操作元素的属性节点,属性名需要和HTML中写的完全一致。
// 获取元素
const userDiv = document.querySelector('[data-user-name]');
// 读取data-user-name属性
const userName = userDiv.getAttribute('data-user-name');
console.log(userName); // 输出:张三
// 修改data-user-age属性
userDiv.setAttribute('data-user-age', '26');
// 新增data-user-gender属性
userDiv.setAttribute('data-user-gender', '男');
使用dataset属性
HTML5为元素提供了dataset属性,这是一个DOMStringMap对象,专门用来访问data-*属性,使用时需要把data-后面的连字符命名转换成驼峰式命名。
| HTML中的属性名 | dataset中的访问名 |
|---|---|
| data-id | dataset.id |
| data-user-name | dataset.userName |
| data-user-age | dataset.userAge |
const userDiv = document.querySelector('[data-user-name]');
// 读取属性
console.log(userDiv.dataset.userName); // 输出:张三
console.log(userDiv.dataset.userAge); // 输出:25
// 修改属性
userDiv.dataset.userAge = '26';
// 新增属性
userDiv.dataset.userEmail = 'test@ipipp.com';
// 删除属性
delete userDiv.dataset.userGender;
使用data-*属性的注意事项
- data-*属性名只能包含小写字母、连字符、数字,不能有大写字母,否则dataset无法正确识别。
- data-*属性值都是字符串类型,如果需要存储数字、对象等类型,需要手动做类型转换,比如用
JSON.parse()解析JSON字符串。 - 不要滥用data-*属性存储大量数据或者敏感数据,大量数据建议用JavaScript变量存储,敏感数据不要放在前端属性中避免泄露。
- 修改data-*属性后,页面不会自动更新,需要手动操作DOM更新对应的显示内容。
实际应用场景示例
比如在列表渲染时给每个列表项绑定对应的ID,点击时获取ID发送请求:
<ul id="list"> <li data-item-id="1">商品1</li> <li data-item-id="2">商品2</li> <li data-item-id="3">商品3</li> </ul>
const list = document.getElementById('list');
list.addEventListener('click', function(e) {
// 判断点击的是li元素
if (e.target.tagName === 'LI') {
const itemId = e.target.dataset.itemId;
console.log('点击的商品ID是:' + itemId);
// 这里可以发送请求获取商品详情
}
});
注意:如果使用jQuery操作data-*属性,jQuery的data()方法会缓存第一次读取的值,后续修改HTML的data-*属性不会同步到jQuery的缓存中,建议统一使用原生API操作避免问题。