功能目标
- 动态生成主列表:从一个数据源生成列表项,避免硬编码。
- 点击高亮切换:点击某项后,该项背景变色以突出显示。
- 展示对应的子数据:根据点击项,显示其关联的子数据。
1. 准备工作
首先,我们需要构建一个数据源作为动态生成列表的基础。以下是示例数据结构
const list = [
{
id: 1,
name: '华为手机',
children: [
{ id: 1003, ername: '华为mt60' }
]
},
{
id: 2,
name: '苹果手机',
children: [
{ id: 1004, ername: 'iphone15mxpro' }
]
},
{
id: 3,
name: 'opponents',
children: [
{ id: 1005, ername: 'oppo16x' }
]
},
{
id: 4,
name: 'JavaScript',
children: [
{ id: 1006, ername: 'nodejs' }
]
},
];
2. HTML结构
<div class="counter">
<ul></ul>
<div class="details">点击上方的项目以查看子数据</div>
</div>
3. css 部分
.counter {
width: 50%;
height: auto;
border: 1px solid red;
border-radius: 8px;
padding: 10px;
}
.counter ul {
margin-bottom: 8px;
padding: 0;
}
.counter ul li {
display: inline-block;
padding: 5px 10px;
background-color: lightseagreen;
border-radius: 8px;
text-align: center;
line-height: 34px;
font-size: 16px;
list-style-type: none;
cursor: pointer;
margin-right: 5px;
}
.active {
background-color: blueviolet;
color: white;
}
.details {
margin-top: 20px;
font-size: 16px;
}
4. JavaScript部分
遍历父元素
- 使用
data-id
属性存储每个列表项的唯一标识。 innerHTML
方法将生成的 HTML 字符串插入页面。
const ulElement = document.querySelector('.counter ul');
let str = '';
list.forEach((item) => {
str += `<li data-id="${item.id}">${item.name}</li>`;
});
ulElement.innerHTML = str;
5. 点击事件与高亮切换
- 通过
classList.add
和classList.remove
实现样式的动态切换。 - 点击某项时,先移除其他项的
active
类,再为当前项添加。
const buttons = document.querySelectorAll('.counter ul li');
buttons.forEach(button => {
button.addEventListener('click', () => {
// 切换高亮样式
buttons.forEach(btn => btn.classList.remove('active'));
button.classList.add('active');
});
});
6. 展示对应子数据
结合 data-id
属性,我们可以根据点击的列表项找到对应的子数据,并展示在页面上:
const detailsDiv = document.querySelector('.details');
buttons.forEach(button => {
button.addEventListener('click', () => {
// 获取当前点击项的 ID
const id = button.getAttribute('data-id');
const selectedItem = list.find(item => item.id == id);
// 展示子数据
if (selectedItem && selectedItem.children.length > 0) {
const child = selectedItem.children[0];
detailsDiv.innerHTML = `子数据:<strong>${child.ername}</strong>`;
} else {
detailsDiv.innerHTML = '没有子数据';
}
});
});
全部代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.counter {
width: 50%;
height: auto;
border: 1px solid red;
border-radius: 8px;
padding: 10px;
}
.counter ul {
margin-bottom: 8px;
padding: 0;
}
.counter ul li {
display: inline-block;
padding: 5px 10px;
background-color: lightseagreen;
border-radius: 8px;
text-align: center;
line-height: 34px;
font-size: 16px;
list-style-type: none;
cursor: pointer;
margin-right: 5px;
}
.active {
background-color: blueviolet;
color: white;
}
.details {
margin-top: 20px;
font-size: 16px;
}
</style>
</head>
<body>
<div class="counter">
<ul></ul>
<div class="details">点击上方的项目以查看子数据</div>
</div>
<script>
// 数据列表
const list = [
{
id: 1,
name: '华为手机',
children: [
{
id: 1003,
ername: '华为mt60'
}
]
},
{
id: 2,
name: '苹果手机',
children: [
{
id: 1004,
ername: 'iphone15mxpro'
}
]
},
{
id: 3,
name: 'opponents',
children: [
{
id: 1005,
ername: 'oppo16x'
}
]
},
{
id: 4,
name: 'JavaScript',
children: [
{
id: 1006,
ername: 'nodejs'
}
]
},
];
const ulElement = document.querySelector('.counter ul');
let str = '';
list.forEach((item) => {
str += `<li data-id="${item.id}">${item.name}</li>`;
});
ulElement.innerHTML = str;
const buttons = document.querySelectorAll('.counter ul li');
const detailsDiv = document.querySelector('.details');
buttons.forEach(button => {
button.addEventListener('click', () => {
buttons.forEach(btn => btn.classList.remove('active'));
button.classList.add('active');
const id = button.getAttribute('data-id');
const selectedItem = list.find(item => item.id == id);
if (selectedItem && selectedItem.children.length > 0) {
const child = selectedItem.children[0];
detailsDiv.innerHTML = `子数据:<strong>${child.ername}</strong>`;
} else {
detailsDiv.innerHTML = '没有子数据';
}
});
});
</script>
</body>
</html>
8. 总结
通过以上实现,我们掌握了:
- 动态生成 HTML 元素 的方法。
- 样式动态切换 和 高亮功能 的实现。
- 基于数据动态展示内容 的技巧。
这种方式不仅适用于简单的列表切换,还能扩展到更复杂的动态展示场景。希望本文对你有所帮助!