原生 Javascript 实现平滑滚动到顶部

平滑滚动到顶部
平滑滚动到顶部

使用JQuery实现页面平滑滚动非常方便,只需要获取到元素,添加点击事件,使用animate,然后将ScrollTop 方法返回或设置匹配元素的滚动条的垂直位置值设置为0即可,只需要几行代码便可以实现,如下代码所示:

/**
 * smooth scroll to top with jquery
 *
 * @author 智慧宫
 * @link   https://lerm.net
 */
$('#scrollUp').click(function(e) {
	e.preventDefault();
	$('html,body').animate({
		scrollTop: 0
	});
});

如果不使用jQuery怎么做才能实现平滑滚动到顶部呢,请看下面的代码,大神忽略

HTML代码

/**
 * smooth scroll to top html
 *
 * @author 智慧宫
 * @link   https://lerm.net
 */
<a type="button" class="tool-btn btn" id="scroll-top" href="javascript:;"  data-toggle="tooltip" data-placement="left" title="飞回顶部">
    <i class="fa fa-chevron-up"></i>
</a>

Javascript代码

获取向上滚动按钮,监听点击事件,在点击事件中执行animate函数:

/**
 * smooth scroll to top
 *
 * @author 智慧宫
 * @link   https://lerm.net
 */
let scrollUp = document.getElementById('scroll-top');
scrollUp.addEventListener('click', e => {
	e.preventDefault();
	animate({
		duration: 700,
		timing: scrollUpEaseOut,
		draw: progress =>
			html.scrollTop = (html.scrollTop * (1 - progress / 7))
	});
})

鉴定滚动事件,执行check 函数;

/**
 * 监听滚动事件,执行check函数
 *
 * @author 智慧宫
 * @link   https://lerm.net
 */
window.addEventListener('scroll', check);

check 用于检查当前的页面位置,若页面向上大于500则添加show class属性,显示向上按钮,否者移除show class属性 ,隐藏向上按钮;

/**
 * check函数
 *
 * @author 智慧宫
 * @link   https://lerm.net
 */
function check () {
	pageYOffset >= 500 && scrollUp.classList.add('show');
	pageYOffset < 500 && scrollUp.classList.remove('show');
}

设定aminate 函数的参数,即时序函数,设定为EaseOut;注意:使用了ES6的箭头函数

/**
 * 时序函数
 *
 * @author 智慧宫
 * @link   https://lerm.net
 */
let circ = timeFraction => 1 - Math.sin(Math.acos(timeFraction > 1 ? timeFraction = 1 : timeFraction));
let makeEaseOut = timing => timeFraction => 1 - timing(1 - timeFraction);
let scrollUpEaseOut = makeEaseOut(circ);

封装动画函数

JavaScript 动画应该通过 requestAnimationFrame 实现。该内置方法允许设置回调函数,以便在浏览器准备重绘时运行。那通常很快,但确切的时间取决于浏览器。

当页面在后台时,根本没有重绘,因此回调将不会运行:动画将被暂停并且不会消耗资源。那很棒。

function animate({timing, draw, duration}) {

  let start = performance.now();

  requestAnimationFrame(function animate(time) {
    // timeFraction 从 0 增加到 1
    let timeFraction = (time - start) / duration;
    if (timeFraction > 1) timeFraction = 1;

    // 计算当前动画状态
    let progress = timing(timeFraction);

    draw(progress); // 绘制

    if (timeFraction < 1) {
      requestAnimationFrame(animate);
    }

  });
}

参数:

  • duration —— 动画运行的总毫秒数。
  • timing —— 计算动画进度的函数。获取从 0 到 1 的小数时间,返回动画进度,通常也是从 0 到 1。
  • draw —— 绘制动画的函数。

当然我们可以改进它,增加更多花里胡哨的东西,但 JavaScript 动画不是经常用到。它们用于做一些有趣和不标准的事情。因此,您大可在必要时再添加所需的功能。

JavaScript 动画可以使用任何时序函数。我们介绍了很多例子和变换,使它们更加通用。与 CSS 不同,我们不仅限于 Bezier 曲线。

draw 也是如此:我们可以将任何东西动画化,而不仅仅是 CSS 属性。

参考:

https://zh.javascript.info/js-animation

发表评论

游客欢迎您