请求实现垂直手风琴.links类自动上下滚动动画(悬停暂停)
实现垂直手风琴内链接列表的自动往返滚动效果
核心思路
通过容器嵌套+requestAnimationFrame动画实现内容的自动上下滚动,结合事件监听控制动画启停,同时利用定位固定margin-text元素。
步骤1:调整布局样式(CSS)
先给手风琴面板和相关元素设置定位规则,确保滚动区域和固定元素的布局正确:
/* 手风琴面板设置相对定位,作为固定元素的参考容器 */ .accordion-panel { position: relative; overflow: hidden; } /* 固定margin-text到面板右侧(可根据需求调整位置) */ .margin-text { position: absolute; right: 1.5rem; top: 0; bottom: 0; margin: 0; /* 可添加自定义样式,比如字体、颜色 */ } /* 滚动容器设置固定高度,隐藏超出内容 */ .links { height: 280px; /* 按需调整,匹配手风琴展开后的高度 */ overflow: hidden; position: relative; padding-right: 8rem; /* 给右侧固定的margin-text留出空间 */ } /* 滚动内容的内层容器,用于动画位移 */ .links-inner { position: absolute; top: 0; left: 0; width: 100%; }
步骤2:实现滚动动画与交互控制(JavaScript)
通过动态创建内层容器,利用requestAnimationFrame实现平滑的往返滚动,同时监听鼠标事件启停动画:
// 遍历所有需要滚动的.links容器 document.querySelectorAll('.links').forEach(container => { // 创建内层容器包裹原有内容 const innerWrap = document.createElement('div'); while (container.firstChild) { innerWrap.appendChild(container.firstChild); } container.appendChild(innerWrap); innerWrap.classList.add('links-inner'); let scrollDir = 1; // 1=向下滚动,-1=向上滚动 const scrollSpeed = 0.4; // 滚动速度,数值越小越慢 let animId; // 滚动动画函数 function runScroll() { const maxScrollDistance = innerWrap.offsetHeight - container.offsetHeight; const currentTop = parseFloat(getComputedStyle(innerWrap).top) || 0; // 计算新的位移值 let newTop = currentTop + scrollDir * scrollSpeed; // 到达边界时反转滚动方向 if (newTop <= -maxScrollDistance) { newTop = -maxScrollDistance; scrollDir = -1; } else if (newTop >= 0) { newTop = 0; scrollDir = 1; } innerWrap.style.top = `${newTop}px`; animId = requestAnimationFrame(runScroll); } // 启动动画 runScroll(); // 鼠标悬停暂停动画 container.addEventListener('mouseenter', () => { cancelAnimationFrame(animId); }); // 鼠标离开继续动画 container.addEventListener('mouseleave', () => { runScroll(); }); });
关键细节说明
- 内层容器的作用:直接移动整个内容块而非修改
scrollTop,能更平滑地实现往返动画,避免滚动到边界时的生硬跳转。 - 边界判断逻辑:通过计算内层容器与外层容器的高度差,精准判断是否到达滚动边界,自动反转方向。
- 性能优化:使用
requestAnimationFrame实现动画,比setInterval更流畅且节省性能。 - 固定元素布局:
margin-text通过绝对定位脱离文档流,始终固定在手风琴面板的指定位置,不受滚动内容影响。
内容的提问来源于stack exchange,提问作者Maria Bastos Proença
相关产品推荐
相关产品推荐

