没有jquery的scrollTop动画

Jas*_*per 79 html javascript css jquery

我试图在不使用jQuery的情况下制作动画"滚动到顶部"效果.

在jQuery中,我通常使用这段代码:

$('#go-to-top').click(function(){ 
      $('html,body').animate({ scrollTop: 0 }, 400);
      return false; 
});
Run Code Online (Sandbox Code Playgroud)

如何在不使用jQuery的情况下为scrollTop设置动画?

Rob*_*ene 160

HTML:

<button onclick="scrollToTop(1000);"></button>
Run Code Online (Sandbox Code Playgroud)

1 #JavaScript(线性):

function scrollToTop(scrollDuration) {
    var scrollStep = -window.scrollY / (scrollDuration / 15),
        scrollInterval = setInterval(function(){
        if ( window.scrollY != 0 ) {
            window.scrollBy( 0, scrollStep );
        }
        else clearInterval(scrollInterval); 
    },15);
}
Run Code Online (Sandbox Code Playgroud)

2#JavaScript(轻松进出):

function scrollToTop(scrollDuration) {
const   scrollHeight = window.scrollY,
        scrollStep = Math.PI / ( scrollDuration / 15 ),
        cosParameter = scrollHeight / 2;
var     scrollCount = 0,
        scrollMargin,
        scrollInterval = setInterval( function() {
            if ( window.scrollY != 0 ) {
                scrollCount = scrollCount + 1;  
                scrollMargin = cosParameter - cosParameter * Math.cos( scrollCount * scrollStep );
                window.scrollTo( 0, ( scrollHeight - scrollMargin ) );
            } 
            else clearInterval(scrollInterval); 
        }, 15 );
}
Run Code Online (Sandbox Code Playgroud)

注意:

  • 持续时间(以毫秒为单位)(1000ms = 1s)
  • 第二个脚本使用cos函数.示例曲线:

在此输入图像描述

由于选民人数众多,我重新检查了几年前写的代码,并尝试对其进行优化.我在代码的底部添加了一些数学解释.

更新(轻松进出):

使用requestAnimationFrame方法完成更流畅的幻灯片/动画. (在大窗户上发生一点点口吃,因为浏览器必须重绘大面积)

function scrollToTop(scrollDuration) {
    var cosParameter = window.scrollY / 2,
        scrollCount = 0,
        oldTimestamp = performance.now();
    function step (newTimestamp) {
        scrollCount += Math.PI / (scrollDuration / (newTimestamp - oldTimestamp));
        if (scrollCount >= Math.PI) window.scrollTo(0, 0);
        if (window.scrollY === 0) return;
        window.scrollTo(0, Math.round(cosParameter + cosParameter * Math.cos(scrollCount)));
        oldTimestamp = newTimestamp;
        window.requestAnimationFrame(step);
    }
    window.requestAnimationFrame(step);
}
/* 
    Explanations:
    - pi is the length/end point of the cosinus intervall (see above)
    - newTimestamp indicates the current time when callbacks queued by requestAnimationFrame begin to fire.
      (for more information see https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame)
    - newTimestamp - oldTimestamp equals the duration

      a * cos (bx + c) + d                      | c translates along the x axis = 0
    = a * cos (bx) + d                          | d translates along the y axis = 1 -> only positive y values
    = a * cos (bx) + 1                          | a stretches along the y axis = cosParameter = window.scrollY / 2
    = cosParameter + cosParameter * (cos bx)    | b stretches along the x axis = scrollCount = Math.PI / (scrollDuration / (newTimestamp - oldTimestamp))
    = cosParameter + cosParameter * (cos scrollCount * x)
*/
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你!我延长了一点,允许滚动到一个特定的元素,浏览器不performance.now一个填充工具()... https://gist.github.com/joshcanhelp/a3a669df80898d4097a1e2c01dea52c1 (8认同)
  • 我能看到这个JSFIDDLE吗?我似乎无法让它发挥作用... (5认同)
  • 请记住,`const` 不是 EcmaScript 5 的一部分,而是具有不同语义的 6。目前只有 Firefox 和 Chrome 以某种方式支持它。在此处阅读更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const (2认同)