如何实现可点击的垂直Accordion(JS)及列表项无限自动滚动?
问题描述
我正在为硕士课程制作网站,想要实现可点击的垂直Accordion组件,点击每个<li>即可展开显示更多信息。目前仅通过CSS实现了hover触发的展开效果,请问如何用JavaScript改为点击触发?另外能否为每个<li>添加无限自动滚动功能?恳请技术帮助。
解决方案
一、改为点击触发的Accordion组件
1. 修改CSS规则
将原有的li:hover样式替换为自定义类.active,通过JS控制类的添加/移除来触发展开/收起:
/* 替换原li:hover样式 */ li.active { -webkit-box-flex : 30vw; -webkit-flex : 30vw; -ms-flex : 30vw; flex : 30vw; }
2. 添加JavaScript交互逻辑
在HTML的</body>标签前插入以下代码,实现点击切换展开状态,支持点击已展开项收起:
document.addEventListener('DOMContentLoaded', function() { const items = document.querySelectorAll('ul li'); items.forEach(item => { item.addEventListener('click', function() { const isActive = this.classList.contains('active'); // 先关闭所有已展开的项 items.forEach(i => i.classList.remove('active')); // 若当前项未激活则展开,否则保持收起 if (!isActive) this.classList.add('active'); }); }); });
二、添加无限自动滚动功能
无限滚动的核心是复制一份内容到容器尾部,滚动到原始内容高度时重置位置,实现无缝循环。
1. 调整HTML结构
给每个<li>内的内容包裹一个统一的容器,方便滚动控制:
<li> <div class="scroll-content"> <!-- 原有的projects内容 --> <div class="projects">...</div> <div class="projects">...</div> </div> </li>
2. 补充CSS样式
确保滚动容器的高度和溢出规则:
.scroll-content { height: 100%; overflow-y: scroll; scrollbar-width: none; /* 可选:隐藏滚动条 */ } /* 针对webkit内核浏览器隐藏滚动条 */ .scroll-content::-webkit-scrollbar { display: none; }
3. 实现自动滚动逻辑
在之前的JS代码中追加以下内容:
// 无限自动滚动逻辑 const scrollContainers = document.querySelectorAll('.scroll-content'); scrollContainers.forEach(container => { // 复制一份内容到容器末尾 const content = container.innerHTML; container.innerHTML += content; let scrollPosition = 0; const scrollSpeed = 1; // 滚动速度,值越大越快 let animationId; function autoScroll() { scrollPosition += scrollSpeed; // 滚动到原始内容高度时重置位置,实现无缝循环 if (scrollPosition >= container.scrollHeight / 2) { scrollPosition = 0; } container.scrollTop = scrollPosition; animationId = requestAnimationFrame(autoScroll); } // 启动自动滚动 autoScroll(); // 鼠标悬停暂停滚动,离开后继续 container.addEventListener('mouseover', () => cancelAnimationFrame(animationId)); container.addEventListener('mouseout', () => autoScroll()); });
完整修改后代码示例
CSS(styles.css)
body { width : 100vw; height : 100vh; margin : 0; } ul, li { margin : 0; padding : 0; list-style : none; } ul { display : flex; overflow : hidden; height : 100vh; width : 100vw; } li { overflow : hidden; -webkit-box-flex : 1; -webkit-flex : 1; -ms-flex : 1; flex : 1; width : 8.3vw; height : calc(100% - 1%); -webkit-transition : -webkit-box-flex 500ms ease-out; -webkit-transition : -webkit-flex 500ms ease-out; transition : -webkit-box-flex 500ms ease-out; transition : -ms-flex 500ms ease-out; transition : flex 500ms ease-out; padding : 20px; -webkit-box-shadow : 2px 0px 4px -1px rgba(0, 0, 0, 0.66); -moz-box-shadow : 2px 0px 4px -1px rgba(0, 0, 0, 0.66); box-shadow : 2px 0px 4px -1px rgba(0, 0, 0, 0.66); } li.active { -webkit-box-flex : 30vw; -webkit-flex : 30vw; -ms-flex : 30vw; flex : 30vw; } .projects { width : 30vw; height : auto; margin-bottom : 5vh; } .scroll-content { height: 100%; overflow-y: scroll; scrollbar-width: none; } .scroll-content::-webkit-scrollbar { display: none; } /* ------- 文本样式 ------- */ a { text-decoration : none; color : black; } a:hover { opacity : 0.5; } .maintitle { width : 100%; font-size : 30px; text-transform : uppercase; font-family : Arial, Helvetica, sans-serif; } .subtitle { width : 150vw; font-size : 20px; font-family : Arial, Helvetica, sans-serif; } img { padding-top : 20px; width : 25vh; height : auto; }
HTML
<!DOCTYPE html> <html lang="en"> <head> <title> MDC 22-23 </title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="styles.css"> </head> <body> <ul> <!-- MICRO-1--> <li> <div class="scroll-content"> <div class="projects"> <a href="matilde/matilde.html"> <div class="maintitle"> Networked Infrastructures</div> <div class="subtitle"> Three geographies (environmental, economic, political)</div> <img src="gif5.gif"> </a> </div> <div class="projects"> <a href="matilde/matilde.html"> <div class="maintitle"> Networked Infrastructures</div> <div class="subtitle"> Three geographies (environmental, economic, political)</div> <img src="gif5.gif"> </a> </div> <div class="projects"> <a href="matilde/matilde.html"> <div class="maintitle"> Networked Infrastructures</div> <div class="subtitle"> Three geographies (environmental, economic, political)</div> <img src="gif5.gif"> </a> </div> </div> </li> <!-- PROJECT 2--> <li> <div class="scroll-content"> <div class="projects"> <a href="matilde/matilde.html"> <div class="maintitle"> Networked Infrastructures</div> <div class="subtitle"> Three geographies (environmental, economic, political)</div> <img src="gif5.gif"> </a> </div> <div class="projects"> <a href="matilde/matilde.html"> <div class="maintitle"> Networked Infrastructures</div> <div class="subtitle"> Three geographies (environmental, economic, political)</div> <img src="gif5.gif"> </a> </div> <div class="projects"> <a href="matilde/matilde.html"> <div class="maintitle"> Networked Infrastructures</div> <div class="subtitle"> Three geographies (environmental, economic, political)</div> <img src="gif5.gif"> </a> </div> </div> </li> <!-- PROJECT 3 --> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li> <li>11</li> <li>12</li> </ul> <script> document.addEventListener('DOMContentLoaded', function() { // 点击切换展开/收起 const items = document.querySelectorAll('ul li'); items.forEach(item => { item.addEventListener('click', function() { const isActive = this.classList.contains('active'); items.forEach(i => i.classList.remove('active')); if (!isActive) this.classList.add('active'); }); }); // 无限自动滚动 const scrollContainers = document.querySelectorAll('.scroll-content'); scrollContainers.forEach(container => { const content = container.innerHTML; container.innerHTML += content; let scrollPosition = 0; const scrollSpeed = 1; let animationId; function autoScroll() { scrollPosition += scrollSpeed; if (scrollPosition >= container.scrollHeight / 2) { scrollPosition = 0; } container.scrollTop = scrollPosition; animationId = requestAnimationFrame(autoScroll); } autoScroll(); container.addEventListener('mouseover', () => cancelAnimationFrame(animationId)); container.addEventListener('mouseout', () => autoScroll()); }); }); </script> </body> </html>
内容的提问来源于stack exchange,提问作者Maria Bastos Proença
相关产品推荐
相关产品推荐

