
本教程将指导您如何优化基于javascript的手风琴(accordion)组件,使其在点击时仅允许一个内容面板展开,同时自动关闭其他已展开项。我们将通过事件委托机制改进现有实现,提升代码效率和用户体验,确保手风琴行为符合预期。
手风琴(Accordion)是一种常见的UI模式,用于在有限空间内展示大量内容,通过点击标题展开或折叠对应的内容区域。一个常见的需求是,当用户点击一个手风琴项时,只允许该项展开,而其他所有已展开的项应自动关闭。本文将详细介绍如何利用JavaScript的事件委托机制来实现这一功能。
在初始的实现中,手风琴组件通常为每个可折叠按钮单独绑定点击事件。这种方法虽然能实现内容的展开与折叠,但当用户点击不同的手风琴项时,所有被点击的项都会保持展开状态,直到再次点击它们才能关闭。这可能导致界面混乱,尤其是在手风琴项较多的情况下。
以下是原始JavaScript代码片段,它允许所有手风琴项独立展开和关闭:
const accordians = document.getElementsByClassName("accordion_btn");
for (var i = 0; i < accordians.length; i += 1) {
accordians[i].onclick = function() {
this.classList.toggle('arrowClass');
var content = this.nextElementSibling;
if (content.style.maxHeight) {
// Accordion is open, needs to be closed
content.style.maxHeight = null;
} else {
// Accordion is closed, needs to be open
content.style.maxHeight = content.scrollHeight + "px";
}
}
}为了实现“单项展开”的效果,我们需要在每次点击手风琴按钮时,首先遍历所有手风琴项,关闭除当前点击项之外的所有已展开项,然后再处理当前点击项的展开/折叠状态。
立即学习“Java免费学习笔记(深入)”;
事件委托是优化此过程的关键。通过将事件监听器绑定到共同的父元素(例如 main 元素),我们可以利用事件冒泡机制捕获所有手风琴按钮的点击事件。这样做的好处是:
以下是优化后的JavaScript代码,它利用事件委托实现了手风琴的单项展开功能:
// 获取所有手风琴按钮的集合
let allAccordionBtns = document.querySelectorAll('.accordion_btn');
// 将事件监听器委托给共同的父元素 `main`
document.querySelector('main').addEventListener('click', e => {
// 检查点击事件的目标是否是手风琴按钮
if (e.target.classList.contains('accordion_btn')) {
// 遍历所有手风琴按钮,关闭除当前点击按钮之外的所有内容面板
allAccordionBtns.forEach(btn => {
// 如果当前遍历的按钮不是被点击的按钮
if (btn !== e.target) {
// 关闭其内容面板
btn.nextElementSibling.style.maxHeight = null;
// 移除箭头类,恢复折叠状态的样式
btn.classList.remove('arrowClass');
}
});
// 处理当前被点击按钮的内容面板
let content = e.target.nextElementSibling;
// 根据当前状态切换内容面板的展开/折叠
// 如果maxHeight等于scrollHeight(已展开),则设置为null(关闭),否则设置为scrollHeight(展开)
content.style.maxHeight = parseFloat(content.style.maxHeight) === parseFloat(content.scrollHeight) ? null : content.scrollHeight + "px";
// 切换当前按钮的箭头类,改变箭头方向
e.target.classList.toggle('arrowClass');
}
});代码解析:
为了使手风琴具有良好的视觉效果和动画,CSS样式和HTML结构至关重要。
HTML结构示例:
<main>
<div class="accordion_container">
<div id="small">General - AD rate $10 ~ 99% off</div>
<div id="accordion_header">General Inbox</div>
<div class="accordion_body">
<div class="accordion_body_item">
<button class="accordion_btn">Inbox one</button>
<div class="accordion_content">
<div class="inner">
<div class="inner_datetime">dd/mm/yyyy</div>
<div class="inner_body">
These cookies allow us or our third party analytics providers to collect information and statistics on use of our services by you and other visitors. These information help us improve our services and products for the benefit of you and others. These
cookies allow us or our third party analytics providers to collect information and statistics on use of our services by you and other visitors. These information help us improve our services and products for the benefit of you and others.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui sint, deserunt cumque nobis illo ut beatae impedit pariatur aliquid minus!
</div>
</div>
</div>
</div>
<!-- 更多 accordion_body_item 结构 -->
<div class="accordion_body_item">
<button class="accordion_btn">Inbox two</button>
<div class="accordion_content">
<div class="inner">
<div class="inner_datetime">dd/mm/yyyy</div>
<div class="inner_body">
These cookies allow us or our third party analytics providers to collect information and statistics on use of our services by you and other visitors. These information help us improve our services and products for the benefit of you and others. These
cookies allow us or our third party analytics providers to collect information and statistics on use of our services by you and other visitors. These information help us improve our services and products for the benefit of you and others.
</div>
</div>
</div>
</div>
<!-- ... -->
</div>
<div class="accordion_footer">
<div id="small">Best Regards | Inbox Team</div>
</div>
</div>
</main>关键CSS样式:
@import url('https://fonts.googleapis.com/css?family=Inter');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 滚动条样式 */
main div.accordion_container::-webkit-scrollbar,
main div.accordion_container .accordion_body .accordion_body_item .accordion_content .inner::-webkit-scrollbar {
width: 4px;
}
/* ... 其他滚动条样式 ... */
main {
background-color: rgba(25, 25, 25, 0.8);
display: grid;
place-items: center;
font-family: 'Inter';
width: 100%;
height: 100vh;
}
main div.accordion_container {
background-color: #efefef;
padding: 10px;
width: 800px;
overflow: auto;
border-radius: 3px;
position: relative;
}
/* ... 头部和底部样式 ... */
main div.accordion_container .accordion_body .accordion_body_item .accordion_btn {
width: 100%;
background-color: gainsboro;
border:none;
border-left: 3px solid transparent; /* 确保hover时不会导致内容跳动 */
border-right: 3px solid transparent;
outline: none;
text-align: left;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
transition: background-color 300ms linear;
}
main div.accordion_container .accordion_body .accordion_body_item .accordion_btn:hover {
background-color: silver;
border-left-color: rgba(19, 2, 153, 1);
color: rgba(19, 2, 153, 1);
border-right-color: rgba(19, 2, 153, 1);
}
main div.accordion_container .accordion_body .accordion_body_item .accordion_btn::before {
content: '▼'; /* 默认向下箭头 */
float: right;
}
main div.accordion_container .accordion_body .accordion_body_item .accordion_btn.arrowClass::before {
content: '▲'; /* 展开时向上箭头 */
}
main div.accordion_container .accordion_body .accordion_body_item .accordion_content {
border-left-width: 3px;
border-left-style: solid;
border-left-color: #777;
border-right-width: 3px;
border-right-style: solid;
border-right-color: #777;
max-height: 0; /* 默认隐藏内容 */
overflow: hidden;
transition: max-height 450ms ease-in-out; /* 展开/折叠动画 */
}
main div.accordion_container .accordion_body .accordion_body_item .accordion_content .inner {
padding: 20px 15px;
font-size: 14px;
background-color: #777;
color: #dfdfdf;
height: 200px; /* 固定内容区域高度,可根据需求调整 */
overflow: auto;
}
/* ... 内容内部样式 ... */CSS要点:
通过采用事件委托机制并结合简单的遍历逻辑,我们可以有效地实现JavaScript手风琴组件的单项展开功能。这种方法不仅优化了代码结构,提高了性能,还提升了用户体验。理解 maxHeight、scrollHeight 和 CSS transition 的协同工作方式是构建流畅手风琴动画的关键。
以上就是JavaScript手风琴组件:实现单项展开与事件委托优化的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号