我找到了一个非常适合此问题的解决方案。下面是我的项目中的一些粘贴代码。基本上可以归结为这个逻辑:
当满足以下任一条件时,滚动事件来自人类:
由于当启用惯性滚动时,Mac 会每 20 毫秒向浏览器发送一次增量递减的滚动事件,因此这是一种非常安全的方法。至少我从来没有失败过。仅检查自上次滚动以来的时间是行不通的,因为如果“虚拟飞轮”仍在运行,即使用户已经没有滚动 3 秒,用户也将无法再次滚动。
this.minScrollWheelInterval = 100; // minimum milliseconds between scrolls
this.animSpeed = 300;
this.lastScrollWheelTimestamp = 0;
this.lastScrollWheelDelta = 0;
this.animating = false;
document.addEventListener('wheel',
(e) => {
const now = Date.now();
const rapidSuccession = now - this.lastScrollWheelTimestamp < this.minScrollWheelInterval;
const otherDirection = (this.lastScrollWheelDelta > 0) !== (e.deltaY > 0);
const speedDecrease = Math.abs(e.deltaY) < Math.abs(this.lastScrollWheelDelta);
const isHuman = otherDirection || !rapidSuccession || !speedDecrease;
if (isHuman && !this.animating) {
this.animating = true; // current animation starting: future animations blocked
$('.something').stop().animate( // perform some animation like moving to the next/previous page
{property: value},
this.animSpeed,
() => {this.animating = false} // animation finished: ready for next animation
)
}
this.lastScrollWheelTimestamp = now;
this.lastScrollWheelDelta = e.deltaY;
},
{passive: true}
);
Run Code Online (Sandbox Code Playgroud)
顺便说一句,有一个警告:Mac 还具有滚动加速功能,即:首先,每个连续事件的增量值都会更高。看起来这个持续时间不会超过 100 毫秒左右。因此,如果您因滚动事件而触发的任何动作/动画持续至少 100 毫秒并同时阻止所有其他动作/动画,那么这永远不是问题。
| 归档时间: |
|
| 查看次数: |
11408 次 |
| 最近记录: |