js实现层叠展开
层叠展开的实现方法
层叠展开(Accordion)是一种常见的UI交互模式,允许用户点击标题展开或折叠内容区域。以下是几种JavaScript实现方式:
DOM操作结合CSS过渡
document.querySelectorAll('.accordion-header').forEach(header => {
header.addEventListener('click', () => {
const content = header.nextElementSibling;
content.style.maxHeight = content.style.maxHeight ? null : `${content.scrollHeight}px`;
});
});
对应CSS:
.accordion-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-out;
}
classList切换实现

const items = document.querySelectorAll('.accordion-item');
items.forEach(item => {
const header = item.querySelector('.accordion-header');
header.addEventListener('click', () => {
item.classList.toggle('active');
});
});
CSS部分:
.accordion-content {
display: none;
}
.accordion-item.active .accordion-content {
display: block;
}
动态高度动画版本

function toggleAccordion(element) {
const content = element.nextElementSibling;
const isOpen = element.getAttribute('aria-expanded') === 'true';
element.setAttribute('aria-expanded', !isOpen);
content.style.height = isOpen ? '0' : `${content.scrollHeight}px`;
content.addEventListener('transitionend', () => {
if (!isOpen) content.style.height = 'auto';
}, { once: true });
}
注意事项
-
添加适当的ARIA属性提升可访问性:
<div class="accordion-header" aria-expanded="false" aria-controls="content1"> -
多级嵌套时需要事件委托:
document.addEventListener('click', (e) => { if (e.target.matches('.accordion-header')) { // 处理逻辑 } }); -
性能优化建议:
- 使用requestAnimationFrame处理动画
- 避免在滚动事件中频繁操作DOM
- 对动态加载的内容使用事件委托
完整组件示例
<div class="accordion">
<div class="accordion-item">
<button class="accordion-header">Section 1</button>
<div class="accordion-content">
<p>Content for section 1</p>
</div>
</div>
<!-- 更多条目 -->
</div>
<style>
.accordion-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.25s ease;
}
</style>
<script>
document.querySelectorAll('.accordion-header').forEach(header => {
header.addEventListener('click', () => {
const item = header.parentNode;
const isOpen = item.classList.contains('active');
// 关闭其他打开的项目
document.querySelectorAll('.accordion-item.active').forEach(openItem => {
if (openItem !== item) {
openItem.classList.remove('active');
openItem.querySelector('.accordion-content').style.maxHeight = '0';
}
});
// 切换当前项目
item.classList.toggle('active');
const content = header.nextElementSibling;
content.style.maxHeight = isOpen ? '0' : `${content.scrollHeight}px`;
});
});
</script>
以上实现方案可根据具体需求选择,现代浏览器都支持这些基本交互效果。如需支持旧版浏览器,可能需要添加polyfill或使用jQuery等库的fallback方案。






