scrollTop animation without jquery

This question already has an answer here:

  • Cross browser JavaScript (not jQuery…) scroll to top animation 18 answers

  • HTML:

    <button onclick="scrollToTop(1000);"></button>
    

    1# JavaScript (linear):

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

    2# JavaScript (ease in and out):

    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 );
    }
    

    Note:

  • Duration in milliseconds (1000ms = 1s)
  • Second script uses the cos function. Example curve:
  • Due to the high amount of up-voters, I rechecked my code I wrote a couple of years ago and tried to optimize it. Further more I added a little mathematical explanation at the bottom of my code.

    UPDATE (ease in and out):

    For a smoother slide/animation, done with the requestAnimationFrame method. (a little bit of stuttering happens on large windows, because the browser has to redraw a wide area)

    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)
    */
    
    链接地址: http://www.djcxy.com/p/3948.html

    上一篇: Object.watch()适用于所有浏览器?

    下一篇: 没有jQuery的scrollTop动画