下面给你一份 *完整详解 + 多场景完整代码示例的《HTML5 data- 自定义数据属性教程》**。包含基础语法、读取/写入方式、JS 交互、事件传参、动态修改、数据绑定和实际项目案例。
内容清晰、可直接用于学习、教学或文档撰写。
⭐ HTML5 data- 自定义数据属性详解*
data-* 属性是 HTML5 用于存储自定义数据的标准方式,常用于:
- 存储与 DOM 元素相关的参数
- 在 JS 中读取 / 修改配置
- 在组件或插件中传递数据
- 与后端返回的数据绑定
- 事件委托中识别点击对象
格式如下:
<div data-xxx="value"></div>
其中:
xxx为自定义名称(必须小写,不能包含大写字母)value为任意字符串(数字、对象均可 JSON 化)
一、基础用法示例(最常见)
<button id="btn" data-id="101" data-type="delete">
删除商品
</button>
<script>
const btn = document.getElementById("btn");
console.log(btn.dataset.id); // "101"
console.log(btn.dataset.type); // "delete"
</script>
二、通过 JavaScript 操作 data-* 属性
1. 读取 data 属性
element.dataset.name
示例:
<div id="user" data-name="李若萱" data-age="20"></div>
<script>
const user = document.getElementById("user");
console.log(user.dataset.name); // 李若萱
console.log(user.dataset.age); // 20
</script>
2. 修改 data 属性
element.dataset.age = "22";
element.dataset.role = "VIP";
3. 删除 data 属性
delete element.dataset.age;
三、data-* 命名规则(驼峰转连字符)
HTML 中用连字符:
<div data-user-name="Jack"></div>
JS 中自动转换为驼峰:
element.dataset.userName // Jack
四、场景示例 1:事件委托中识别点击对象(非常常用)
适用于列表、导航栏、商品卡片等。
<ul id="menu">
<li data-page="home">首页</li>
<li data-page="products">商品</li>
<li data-page="contact">联系</li>
</ul>
<script>
document.getElementById("menu").addEventListener("click", function(e) {
if (e.target.dataset.page) {
console.log("跳转到:" + e.target.dataset.page);
}
});
</script>
五、场景示例 2:作为组件参数(轮播图/弹窗常用)
<div class="slider"
data-autoplay="true"
data-delay="3000"
data-direction="horizontal">
</div>
JS 初始化:
const slider = document.querySelector(".slider");
const config = {
autoplay: slider.dataset.autoplay === "true",
delay: Number(slider.dataset.delay),
direction: slider.dataset.direction
};
console.log(config);
六、场景示例 3:存储 JSON 数据
<div id="product"
data-info='{"id":1001,"price":299,"title":"运动鞋"}'>
</div>
<script>
const p = document.getElementById("product");
const info = JSON.parse(p.dataset.info);
console.log(info.id); // 1001
console.log(info.price); // 299
console.log(info.title); // 运动鞋
</script>
七、场景示例 4:结合 CSS 使用 data 属性(高级技巧)
<style>
button[data-state="danger"] {
background: red;
color: white;
}
</style>
<button data-state="danger">删除</button>
无需 JS 即可控制样式,非常灵活。
八、场景示例 5:用于动画控制
<div class="box" data-speed="2" data-distance="200"></div>
<script>
const box = document.querySelector(".box");
let speed = Number(box.dataset.speed);
let distance = Number(box.dataset.distance);
console.log(speed, distance);
</script>
九、示例:列表动态点击加载数据
<ul id="list">
<li data-id="1" data-name="小明">小明</li>
<li data-id="2" data-name="小红">小红</li>
<li data-id="3" data-name="小李">小李</li>
</ul>
<div id="info"></div>
<script>
document.getElementById("list").addEventListener("click", e => {
if (!e.target.dataset.id) return;
document.getElementById("info").innerText =
`ID: ${e.target.dataset.id},姓名: ${e.target.dataset.name}`;
});
</script>
十、动态创建带 data-* 属性的 DOM
let li = document.createElement("li");
li.dataset.index = 5;
li.dataset.title = "示例标题";
document.body.appendChild(li);
十一、data-* 属性 vs JS 全局变量 vs DOM 属性并存区别
| 类型 | 存储位置 | 特点 |
|---|---|---|
data-* | 存储于 DOM,标准方式 | 推荐方式,结构化 |
| JS 全局变量 | JS 内存 | 不适用于 DOM 数据 |
| DOM 属性 | element.xxx | 不建议随意扩展 |
data- 是 HTML 官方标准扩展 DOM 数据的方式*
十二、综合完整示例:商品卡片点击加入购物车
<div class="item"
data-id="3001"
data-price="199"
data-title="蓝牙耳机">
<h3>蓝牙耳机</h3>
<button class="add">加入购物车</button>
</div>
<script>
document.querySelector(".item .add").onclick = function(e) {
const item = e.target.parentElement;
const id = item.dataset.id;
const price = Number(item.dataset.price);
const title = item.dataset.title;
console.log(`加入购物车:${title} (ID:${id}) ¥${price}`);
};
</script>
✔ 总结(背一下就行)
data-*用于存储自定义数据,是 HTML5 推荐方式- JS 使用
element.dataset.xxx访问 - HTML 中连字符 → JS 自动转驼峰
- 配合事件委托、组件配置、样式控制非常强大
- 可以存 JSON、数字、字符串等
明白,我帮你整理一个完整实战示例,演示如何在 购物车、Tab 切换、懒加载场景中使用 data-* 属性,全部都是可直接运行的 HTML5+JS 示例,方便你学习和项目参考。
1️⃣ 购物车示例(动态加入/删除商品)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>购物车 data-* 示例</title>
<style>
body{font-family:Arial;margin:20px}
.item{border:1px solid #ccc;padding:12px;margin-bottom:12px;border-radius:6px;display:flex;justify-content:space-between;align-items:center}
.cart{margin-top:20px;border:1px solid #eee;padding:12px;border-radius:6px;background:#fafafa}
</style>
</head>
<body>
<h2>商品列表</h2>
<div class="item" data-id="101" data-title="蓝牙耳机" data-price="199">
<span>蓝牙耳机 ¥199</span>
<button class="add">加入购物车</button>
</div>
<div class="item" data-id="102" data-title="无线鼠标" data-price="89">
<span>无线鼠标 ¥89</span>
<button class="add">加入购物车</button>
</div>
<div class="item" data-id="103" data-title="机械键盘" data-price="499">
<span>机械键盘 ¥499</span>
<button class="add">加入购物车</button>
</div>
<div class="cart">
<h3>购物车</h3>
<ul id="cartList"></ul>
<strong id="total">总计: ¥0</strong>
</div>
<script>
const cartList = document.getElementById('cartList');
const totalEl = document.getElementById('total');
let total = 0;
document.querySelectorAll('.item .add').forEach(btn => {
btn.addEventListener('click', e => {
const item = e.target.parentElement;
const id = item.dataset.id;
const title = item.dataset.title;
const price = Number(item.dataset.price);
total += price;
const li = document.createElement('li');
li.textContent = `${title} ¥${price} `;
const removeBtn = document.createElement('button');
removeBtn.textContent = '删除';
removeBtn.addEventListener('click', ()=> {
total -= price;
li.remove();
totalEl.textContent = `总计: ¥${total}`;
});
li.appendChild(removeBtn);
cartList.appendChild(li);
totalEl.textContent = `总计: ¥${total}`;
});
});
</script>
</body>
</html>
2️⃣ Tab 切换示例(通过 data-tab 识别内容)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tab 切换 data-* 示例</title>
<style>
.tabs{display:flex;gap:10px;margin-bottom:10px}
.tabs button{padding:8px 12px;border:1px solid #ccc;background:#f5f5f5;border-radius:4px;cursor:pointer}
.tabs button.active{background:#1d72ff;color:#fff;border-color:#1d72ff}
.tab-content{border:1px solid #eee;padding:12px;border-radius:6px}
.tab-content > div{display:none}
.tab-content > div.active{display:block}
</style>
</head>
<body>
<div class="tabs">
<button data-tab="1" class="active">首页</button>
<button data-tab="2">商品</button>
<button data-tab="3">关于</button>
</div>
<div class="tab-content">
<div data-tab="1" class="active">这是首页内容</div>
<div data-tab="2">这里是商品列表</div>
<div data-tab="3">关于我们介绍</div>
</div>
<script>
const tabButtons = document.querySelectorAll('.tabs button');
const tabContents = document.querySelectorAll('.tab-content > div');
tabButtons.forEach(btn => {
btn.addEventListener('click', () => {
const tabId = btn.dataset.tab;
tabButtons.forEach(b=>b.classList.remove('active'));
tabContents.forEach(c=>c.classList.remove('active'));
btn.classList.add('active');
document.querySelector(`.tab-content > div[data-tab="${tabId}"]`).classList.add('active');
});
});
</script>
</body>
</html>
3️⃣ 图片懒加载示例(使用 data-src 属性)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图片懒加载 data-* 示例</title>
<style>
img{display:block;margin-bottom:20px;width:100%;max-width:400px;border-radius:6px}
</style>
</head>
<body>
<h2>图片懒加载示例</h2>
<img data-src="https://picsum.photos/id/1015/600/400" alt="示例1" class="lazy">
<img data-src="https://picsum.photos/id/1016/600/400" alt="示例2" class="lazy">
<img data-src="https://picsum.photos/id/1018/600/400" alt="示例3" class="lazy">
<script>
const lazyImages = document.querySelectorAll('img.lazy');
const observer = new IntersectionObserver((entries, obs) => {
entries.forEach(entry => {
if(entry.isIntersecting){
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove('lazy');
obs.unobserve(img);
}
});
}, {rootMargin: "0px 0px 50px 0px"});
lazyImages.forEach(img => observer.observe(img));
</script>
</body>
</html>
发表回复