需求问询:实现按Ctrl键批量展开/折叠所有Accordion(含嵌套)
实现Ctrl键全局切换所有Accordion展开/折叠
要实现按下Ctrl键全局切换所有Accordion(含嵌套)的展开/折叠状态,我们只需要在原有JS代码基础上添加全局键盘事件监听,同时统一展开/折叠的逻辑即可,无需修改CSS和HTML结构(如果需要嵌套Accordion,直接在panel里加对应元素就行)。
修改后的完整JavaScript代码
// 获取所有accordion元素(包括嵌套的) const accs = document.querySelectorAll('.accordion'); // 记录全局展开状态 let isAllExpanded = false; // 封装单个accordion的切换逻辑 function toggleAccordion(accordion, targetState) { const panel = accordion.nextElementSibling; const isActive = accordion.classList.contains('active'); // 根据目标状态决定展开或折叠,忽略当前状态 if (targetState) { if (!isActive) { accordion.classList.add('active'); panel.style.maxHeight = panel.scrollHeight + "px"; setTimeout(() => panel.style.maxHeight = "unset", 200); } } else { if (isActive) { accordion.classList.remove('active'); panel.style.maxHeight = panel.scrollHeight + "px"; setTimeout(() => panel.style.maxHeight = null, 50); } } } // 给单个accordion绑定点击事件 accs.forEach(acc => { acc.addEventListener('click', function() { // 点击时切换自身状态,不影响全局状态 const panel = this.nextElementSibling; if (panel.style.maxHeight) { panel.style.maxHeight = panel.scrollHeight + "px"; setTimeout(() => panel.style.maxHeight = null, 50); this.classList.remove('active'); } else { panel.style.maxHeight = panel.scrollHeight + "px"; setTimeout(() => panel.style.maxHeight = "unset", 200); this.classList.add('active'); } }); }); // 监听全局键盘事件,处理Ctrl键 document.addEventListener('keydown', function(e) { // 只响应Ctrl键,且避免按住不放重复触发 if (e.ctrlKey && !e.repeat) { isAllExpanded = !isAllExpanded; // 遍历所有accordion,统一设置状态 accs.forEach(acc => toggleAccordion(acc, isAllExpanded)); } });
关键改动说明
- 改用
document.querySelectorAll('.accordion'):能获取页面中所有类名为accordion的元素,包括嵌套在panel里的,完美支持嵌套场景。 - 封装
toggleAccordion函数:把展开/折叠的逻辑抽出来,不管是单个点击还是全局控制都能复用,避免代码冗余。 - 全局状态变量
isAllExpanded:记录当前所有accordion的全局状态,确保按下Ctrl键时统一切换到目标状态。 - 键盘事件优化:添加
!e.repeat判断,防止按住Ctrl键不放时多次触发切换。
嵌套Accordion示例(HTML部分)
如果需要嵌套Accordion,直接在panel里添加即可,代码会自动识别:
<button class="accordion">主Accordion</button> <div class="panel"> <p>主面板内容</p> <!-- 嵌套的Accordion --> <button class="accordion">嵌套Accordion</button> <div class="panel"> <p>嵌套面板内容</p> </div> </div>
CSS和原有HTML结构无需修改,直接替换JS代码就能实现需求。
内容的提问来源于stack exchange,提问作者myoung
相关产品推荐
相关产品推荐

