如何实现滚动时active项居中的CSS垂直滚动选择菜单
解决方案
现有代码问题修正
- 首先修复HTML语法错误:id是唯一标识,你重复给所有a标签加
id="list"不符合规范,统一改为class="list-item" - 现有逻辑仅切换了
active类,没有同步控制菜单列表的滚动位置,所以激活项不会自动对齐到箭头中间 - CSS存在拼写错误:
widht需改为width,同时需给列表容器设置固定的可视高度,配合滚动对齐逻辑
核心修复代码示例
JS逻辑(添加滚动对齐)
const menuList = document.querySelector("#menulist"); const listItems = document.querySelectorAll(".list-item"); let curIndex = 0; const len = listItems.length; // 每项高度,和CSS里设置的数值保持一致即可 const itemHeight = 74; function activeMenu(e) { e.preventDefault(); // 兼容wheel事件的滚动方向判断 if (e.deltaY < 0) { curIndex = curIndex > 0 ? curIndex - 1 : 0; } else { curIndex = curIndex < len -1 ? curIndex +1 : len -1; } // 切换active类 listItems.forEach(item => item.classList.remove("active")); listItems[curIndex].classList.add("active"); // 计算滚动位置,让激活项对齐到容器中间 const scrollTop = curIndex * itemHeight - (menuList.clientHeight / 2) + itemHeight /2; menuList.scrollTo({ top: scrollTop, behavior: 'smooth' }) } menuList.addEventListener('wheel', activeMenu);
CSS调整
/* 给列表容器设置固定可视高度,开启滚动对齐 */ .vertical-menu .list { height: 300px; overflow-y: auto; scroll-snap-type: y mandatory; position: relative; } .vertical-menu .list a { height: 74px; line-height: 50px; scroll-snap-align: center; } /* 修正宽度拼写错误 */ .vertical-menu .left, .vertical-menu .right { width: 10%; align-items: center; }
推荐Vue组件库直接使用
你可以直接用成熟的Vue组件库实现该效果,无需自己手动编写基础逻辑:
- Vant的Picker组件:支持垂直滚轮选择,默认就是激活项居中的效果,自定义样式即可匹配你的设计
- NutUI的Picker选择器:同样支持垂直滚动选择,适配多端场景
- Element Plus的虚拟化选择器:如果选项数量较多,用这个性能更好,也支持自定义展示样式
内容的提问来源于stack exchange,提问作者Welldy Rosman
相关产品推荐
相关产品推荐

