import smoothscroll from 'smoothscroll-polyfill';
// or if linting/typescript complains
import * as smoothscroll from 'smoothscroll-polyfill';
// kick off the polyfill!
smoothscroll.polyfill();
<script src="https://cdn.jsdelivr.net/gh/LieutenantPeacock/SmoothScroll@1.2.0/src/smoothscroll.min.js" integrity="sha384-UdJHYJK9eDBy7vML0TvJGlCpvrJhCuOPGTc7tHbA+jHEgCgjWpPbmMvmd/2bzdXU" crossorigin="anonymous"></script>
<!-- Taken from one of the library examples -->
Easing: <select id="easings"></select>
<button id="to-bottom">Scroll To Bottom</button>
<br>
<button id="to-top" style="margin-top: 5000px;">Scroll To Top</button>
function easeCubicOut(t) {
return --t * t * t + 1;
}
创建一个虚拟数组并用通过easing函数传输的数据填充它。稍后你就会明白为什么我们需要它:
// easing function will take care of decrementing t at each call (too lazy to test it at the moment. If it doesn't, just pass it a decrementing value at each call)
let t = 60;
const dummyPoints = new Array(60).fill(0).map(()=> easeCubicOut(t));
const dummyPointsSum = dummyPoints.reduce((a, el) => {
a += el;
return a;
}, 0);
9条答案
按热度按时间svgewumm1#
使用smoothscroll polyfill(适用于所有浏览器的解决方案),易于应用且具有轻量级依赖性:https://github.com/iamdustan/smoothscroll
一旦你通过npm或yarn安装了它,就把它添加到你的main*.js,.ts* 文件中(首先执行的文件)
i5desfxk2#
IE/Edge/Safari不完全支持行为选项,所以你必须自己实现一些东西。我相信jQuery已经有了一些东西,但是如果你没有使用jQuery,这里有一个纯JavaScript实现:
如果您需要水平滚动:
一个示例调用是:
mrphzbgm3#
关于平滑滚动的更全面的方法列表,请参见我的答案here。
window.requestAnimationFrame
可用于在精确的时间量内执行平滑滚动。为了平滑地垂直滚动,可以使用以下函数。注意,水平滚动可以用大致相同的方式完成。
演示:
x一个一个一个一个x一个一个二个一个x一个一个三个一个
对于更复杂的情况,可以使用SmoothScroll.js library,它可以处理垂直和水平方向的平滑滚动、在其他容器元素内部的滚动、不同的缓动行为、从当前位置相对滚动等等,它还支持大多数没有原生平滑滚动的浏览器。
nhn9ugyo4#
以上这些变通方法弥补了Safari对行为支持的不足。
仍然有必要检测何时需要变通方案。
这个小函数将检测浏览器是否支持平滑滚动,在Safari上返回false,在Chrome和Firefox上返回true:
x一个一个一个一个x一个一个二个x
更新
Safari技术预览版本139(Safari 15.4)测试显示支持
scrollBehavior smooth
,因此我们可能会在15.4中看到支持。trnvg8h35#
具有最平滑性能的解决方案是使用requestAnimationFrame,特别是在您希望合并缓动的情况下:
如果你想稍后取消滚动,你需要有一个对你的requestAnimationFrame的引用(在你使用requestAnimationFrame(step)的任何地方都这样做):
现在,如果您想对滚动使用缓动,并在滚动操作之间设置超时,该怎么办?
创建一个包含60个元素的数组(requestAnimationFrame通常每秒调用60次。从技术上讲,这与浏览器的刷新率无关,但60是最常见的数字。)我们将以非线性方式填充此数组,然后使用这些数字来控制requestAnimationFrame每一步的滚动量:
选择一个缓动函数。假设我们在做一个三次缓动:
创建一个虚拟数组并用通过easing函数传输的数据填充它。稍后你就会明白为什么我们需要它:
Map缓减点使用每个虚拟点的帮助与虚拟点之比总和:
在滚动功能中,我们将进行一些调整:
k4emjkb16#
适用于Safari的一个简单jQuery修复:
4ioopgfo7#
结合George Daniel和terrymorse的回答,下面的代码可以用于所有使用原生JavaScript的浏览器支持。
由于,Chrome,Firefox支持CSS,
scroll-behavior: smooth;
对于不支持此属性的浏览器,我们可以在下面添加。超文本:
CSS:
JavaScript语言:
kr98yfug8#
另一种可能的解决方案,具有“缓和”效果。
受到前面给出的一些答案的启发,
一个关键的区别是使用“步速”而不是指定持续时间,我发现基于固定步速计算每一步的长度会创建一个平滑的“缓出”效果,因为随着滚动接近目标点,步数会增加。
希望下面的代码易于理解。
这是我多年来受益于这个伟大的社区后对SO的第一次贡献。建设性的批评是非常赞赏的。
lskq00tm9#
感谢T.Dayya,我已经结合了关于这个主题的一些答案,这里是带有扩展函数scrollSmoothIntoView的ts模块。
使用html_element.scrollSmoothIntoView()函数。