我正在寻找一个简单的,跨浏览器“滚动到顶部”的动画,我可以应用到一个链接。我不想需要一个JS库,如jQuery/Moo等。

// jQuery Equivilant to convert to pure JS...
$('html, body').animate({scrollTop:0}, 400);

对于那些在跳进图书馆之前应该100%学习JS的人来说,我是一个完美的例子。:(


当前回答

一件容易的事。

var scrollIt = function(time) {
    // time = scroll time in ms
    var start = new Date().getTime(),
        scroll = document.documentElement.scrollTop + document.body.scrollTop,
        timer = setInterval(function() {
            var now = Math.min(time,(new Date().getTime())-start)/time;
            document.documentElement.scrollTop
                = document.body.scrollTop = (1-time)/start*scroll;
            if( now == 1) clearTimeout(timer);
        },25);
}

其他回答

另一种基于上述解决方案的跨浏览器方法

function doScrollTo(to, duration) {
    var element = document.documentElement;

        var start = element.scrollTop,
        change = to - start,
        increment = 20,
        i = 0;

    var animateScroll = function(elapsedTime) {
        elapsedTime += increment;
        var position = easeInOut(elapsedTime, start, change, duration);
        if (i === 1 && window.scrollY === start) {
            element = document.body;
            start = element.scrollTop;
        }
        element.scrollTop = position;
        if (!i) i++;
        if (elapsedTime < duration) {
            setTimeout(function() {
                animateScroll(elapsedTime);
            }, increment);
        }
    };

    animateScroll(0);
}

诀窍在于控制实际的滚动变化,如果它为零,则更改滚动元素。

平滑滚动现在在所有现代浏览器中都是默认实现的。 您还可以对其进行填充,以获得旧浏览器的支持。

// Scroll to specific values
// scrollTo is the same
window.scroll({
  top: 2500, 
  left: 0, 
  behavior: 'smooth'
});

// Scroll certain amounts from current position 
window.scrollBy({ 
  top: 100, // could be negative value
  left: 0, 
  behavior: 'smooth' 
});

// Scroll to a certain element
document.querySelector('.hello').scrollIntoView({ 
  behavior: 'smooth' 
});

// Scroll certain amounts from current position for any element
document.querySelector('.scrollable-element').scrollBy({
  top: 100, 
  behavior: 'smooth'
});

// Scroll to top
var element = document.querySelector('.scrollable-element');
element.scrollBy({
  top: -element.scrollTop, 
  behavior: 'smooth'
});

来源:https://css-tricks.com/snippets/jquery/smooth-scrolling/

看来已经有很多解决方案了。不管怎样,这是另一个,使用简化方程。

// first add raf shim
// http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

// main function
function scrollToY(scrollTargetY, speed, easing) {
    // scrollTargetY: the target scrollY property of the window
    // speed: time in pixels per second
    // easing: easing equation to use

    var scrollY = window.scrollY || document.documentElement.scrollTop,
        scrollTargetY = scrollTargetY || 0,
        speed = speed || 2000,
        easing = easing || 'easeOutSine',
        currentTime = 0;

    // min time .1, max time .8 seconds
    var time = Math.max(.1, Math.min(Math.abs(scrollY - scrollTargetY) / speed, .8));

    // easing equations from https://github.com/danro/easing-js/blob/master/easing.js
    var easingEquations = {
            easeOutSine: function (pos) {
                return Math.sin(pos * (Math.PI / 2));
            },
            easeInOutSine: function (pos) {
                return (-0.5 * (Math.cos(Math.PI * pos) - 1));
            },
            easeInOutQuint: function (pos) {
                if ((pos /= 0.5) < 1) {
                    return 0.5 * Math.pow(pos, 5);
                }
                return 0.5 * (Math.pow((pos - 2), 5) + 2);
            }
        };

    // add animation loop
    function tick() {
        currentTime += 1 / 60;

        var p = currentTime / time;
        var t = easingEquations[easing](p);

        if (p < 1) {
            requestAnimFrame(tick);

            window.scrollTo(0, scrollY + ((scrollTargetY - scrollY) * t));
        } else {
            console.log('scroll done');
            window.scrollTo(0, scrollTargetY);
        }
    }

    // call it once to get started
    tick();
}

// scroll it!
scrollToY(0, 1500, 'easeInOutQuint');

改编自下面的回答:

function scroll(y, duration) {

    var initialY = document.documentElement.scrollTop || document.body.scrollTop;
    var baseY = (initialY + y) * 0.5;
    var difference = initialY - baseY;
    var startTime = performance.now();

    function step() {
        var normalizedTime = (performance.now() - startTime) / duration;
        if (normalizedTime > 1) normalizedTime = 1;

        window.scrollTo(0, baseY + difference * Math.cos(normalizedTime * Math.PI));
        if (normalizedTime < 1) window.requestAnimationFrame(step);
    }
    window.requestAnimationFrame(step);
}

这应该允许你平滑地滚动(余弦函数)从任何地方到指定的“y”。

一件容易的事。

var scrollIt = function(time) {
    // time = scroll time in ms
    var start = new Date().getTime(),
        scroll = document.documentElement.scrollTop + document.body.scrollTop,
        timer = setInterval(function() {
            var now = Math.min(time,(new Date().getTime())-start)/time;
            document.documentElement.scrollTop
                = document.body.scrollTop = (1-time)/start*scroll;
            if( now == 1) clearTimeout(timer);
        },25);
}