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

为什么使用.bind(mousewheel)绑定的滚轮滚动体验非常不自然?

类iOS日期选择器滚动效果实现方案

现有代码问题

  • 直接监听mousewheel事件时固定每次增减1度,滚动速度和滚轮滑动幅度完全无关,所以速度始终固定
  • 给.outer_box设置的0.1s过渡时长过短,且每次wheel事件触发都会打断正在进行的过渡,完全没有惯性缓动效果
  • scroll事件不触发是因为你给body设置了overflow-y: hidden,页面本身没有可滚动高度,自然不会触发scroll事件

修改方案

通过维护目标旋转值、当前渲染值做差值缓动计算,配合requestAnimationFrame实现平滑的惯性滚动效果,修改后的代码如下:

修改后的JavaScript代码

var targetCounter = 0; // 目标旋转角度
var currentCounter = 0; // 当前实际渲染的角度
var easeFactor = 0.08; // 缓动系数,数值越大滚动响应越快
var step = 16.36363636; // 每个选项对应的旋转角度,和CSS中每个in_box的rotateX差值保持一致
// 兼容全浏览器的wheel事件监听
$(document).on("wheel", function(event) {
    event.preventDefault();
    // 根据滚轮滚动方向和幅度计算,向下滚增加角度,向上滚减少角度
    var delta = event.originalEvent.deltaY > 0 ? step : -step;
    targetCounter += delta;
    // 可选:添加边界限制,避免无意义的无效滚动
    targetCounter = Math.max(0, Math.min(targetCounter, 360));
})
// 逐帧渲染实现平滑过渡
function animate() {
    // 缓动计算:当前值逐步靠近目标值,模拟惯性效果
    currentCounter += (targetCounter - currentCounter) * easeFactor;
    // 浮点误差修正,避免无限次小数运算
    if (Math.abs(targetCounter - currentCounter) < 0.01) {
        currentCounter = targetCounter;
    }
    $(".outer_box").css({"transform":"perspective(1000px) rotateX("+currentCounter+"deg)"})
    requestAnimationFrame(animate);
}
// 启动动画循环
animate();

CSS调整

把.outer_box的transition属性移除即可,避免和JS动画冲突:

.outer_box{
    width: 100vw;
    height: 100%;
    position: relative;
    transform: perspective(1000px) rotateX(.1deg);
    transform-style: preserve-3d;
    transition: none;
}

调整后滚动速度会和滚轮滑动幅度正相关,停止滚动时会有自然的减速缓出效果,和原生滚动体验一致,也可以根据自己的需求调整easeFactor参数调整滚动灵敏度。
内容的提问来源于stack exchange,提问作者m4424

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 19:39:02