排除 CSS 的 scroll-snap
,在 Safari 下会奇怪地带动 body
或其他先祖元素滚动,且浏览器兼容也不好。
如果有强迫症的话,定时一段时间检测滚动停止后,再滚动到最近的位置不是很丝滑。假设内容为一堆 24px
高的列表项目:
对于触控,在 scrollend
时计算出最后一小段时间的加速度,然后平滑滚动到对应的位置就可以。
对于鼠标,因为不知道滚动什么时候停止,以及触控板和鼠标的滚动方式也千奇百怪,想到一个基本上不可行的方法:每次触发 wheel
事件后,根据最后一小段时间的 deltaY
和时间的关系插值,推测出滚动结束的时间和终点位置,记 positionOffset
为预期终点位置和最近元素坐标间的距离,time
为允许的缓冲时间,以 1px
为最小分度,每隔 Math.abs(positionOffset) / time
让 scrollTop++
或 --
。数值发生变化时(什么数值?)取消之前的计时并重新计时。显然这很麻烦而且根本没有头绪。
有可以支的招吗?
1
w3cfed 2020-09-06 02:00:38 +08:00
```javascript
const scrollToTop = () => { const c = document.documentElement.scrollTop || document.body.scrollTop; if (c > 0) { window.requestAnimationFrame(scrollToTop); window.scrollTo(0, c - c / 8); } } scrollToTop() ``` // 事例 `window.requestAnimationFrame()` 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。 `requestAnimationFrame` 优势:由系统决定回调函数的执行时机。60Hz 的刷新频率,那么每次刷新的间隔中会执行一次回调函数,不会引起丢帧,不会卡顿。 来之整理博客内容 [How to scroll to the top of the page smoothly? ]( https://github.com/martinageradams/blog/issues/11) |
2
w3cfed 2020-09-06 05:00:09 +08:00
不知道这个有没有用
window.scrollTo({ behavior: "smooth" }) |
3
AlphaRobert OP @w3cfed 这个只是平滑滚动,但是意图在持续触发 wheel 事件时,预测滚动终点,并在一连串事件结束后能吸附到最近的整格(例如 Apple Watch 的 TableView )
|
4
w3cfed 2020-09-06 11:07:31 +08:00
@AlphaRobert 这个我就不会啦
|
5
xiaoming1992 2020-09-06 23:17:04 +08:00 via Android
“对了,Scroll Snap 有个 polyfill:css-scroll-snap-polyfill
“可以让 Chrome 63,Firefox 57,Safari 11 浏览器都有效果。” 节选自 https://www.zhangxinxu.com/wordpress/2018/11/know-css-scroll-snap/ |
6
ccraohng 2020-09-07 07:17:52 +08:00 via iPhone
可以触控的 有 start 和 end 事件,可以对动画结束。
wheel 事件,用 setTimeout 来模拟结束事件 |