You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现滚动时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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 21:06:03