跨浏览器 JavaScript(不是 jQuery...)滚动到顶部动画

Posted

技术标签:

【中文标题】跨浏览器 JavaScript(不是 jQuery...)滚动到顶部动画【英文标题】:Cross browser JavaScript (not jQuery...) scroll to top animation 【发布时间】:2012-02-13 15:10:05 【问题描述】:

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

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

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

【问题讨论】:

+1 表示 想要使用 jQuery,有正当理由 :) 为了获得灵感,您可以查看这些库的源代码,例如jquery-1.7.1.js. 见这里:***.com/questions/1144805/… @seand javascript 不是 jQuery,但 jQuery 是 JavaScript。如果一个人(比如 OP)想学习 JavaScript,他不应该接触任何臃肿的库,除非他们知道如何用 JavaScript 编写相同的代码。 @RobW 使用像 jQuery 这样的库有助于抽象出跨浏览器的差异,所以我认为它对 Web 开发至关重要;如果存在完美的实现并且可以免费获得,那么您不需要知道这些差异 @seand 这就是我们生产蹩脚程序员的方式。他们不懂语言,但可以产生无限量的 jQuery 代码,因为他们知道。这会导致诸如将所有内容存储在 DOM 中(因为有时他们甚至不知道什么是变量,而不是 var something = $(...)),在每个函数中重新创建大量对象(他们知道变量,但不知道 var veryBigObject = ...函数顶部有几百个属性会破坏性能)。而且很多时候他们甚至不知道该语言的名称是 Javascript,而不是 jQuery。 【参考方案1】:

简单。

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

【讨论】:

或者只是window.scrollTo(x, y); 虽然它没有动画。 我为.scrollTop.scrollLeft 提供了一个替代选项。 @NiettheDarkAbsol 这是唯一关心 body.scrolltop 和 documentElement.scrolltop 的函数。但是有一些错误,例如滚动从未使用,错过分号等。请您修改一下。 @DenizPorsuk 你说得对“未使用滚动”,在计算滚动位置时它应该是*scroll。但是,我没有看到任何丢失的;...【参考方案2】:
function scrollTo(element, to, duration) 
    if (duration <= 0) return;
    var difference = to - element.scrollTop;
    var perTick = difference / duration * 10;

    setTimeout(function() 
        element.scrollTop = element.scrollTop + perTick;
        if (element.scrollTop === to) return;
        scrollTo(element, to, duration - 10);
    , 10);

演示:

function runScroll() 
  scrollTo(document.body, 0, 600);

var scrollme;
scrollme = document.querySelector("#scrollme");
scrollme.addEventListener("click",runScroll,false)

function scrollTo(element, to, duration) 
  if (duration <= 0) return;
  var difference = to - element.scrollTop;
  var perTick = difference / duration * 10;

  setTimeout(function() 
    element.scrollTop = element.scrollTop + perTick;
    if (element.scrollTop == to) return;
    scrollTo(element, to, duration - 10);
  , 10);
<p>Very long page.Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page.  Very long page.Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page.  Very long page.Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page.  Very long page.Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page.  Very long page.Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page. Very long page.
</p>
<button id=scrollme type="button">To the top</button>

【讨论】:

document.documentElement 而不是 document.body(除非您设置 CSS:bodyheight:100%;)。使用此概念的工作演示:jsfiddle.net/S5ALP/1 @RobW 您的添加在 Google Chrome @ Ubuntu Linux 中不起作用 在 Firefox 9.0 和 Ubuntu 中也是如此 :)。您的代码在 Firefox 中失败,但在 Chrome 中有效,我的代码在 Chrome 中失败,但在 FF 中有效。 修改它以使用 top.window.scroll(0, value) 而不是 element.scrollTop = value 使它在 Chrome 和 Firefox (Ubuntu) 中都可以工作。 :) 只是抛出这个 sn-p 不适用于 chrome 版本 69.0.3497.100,这是截至目前的最新版本。【参考方案3】:

我修改了 TimWolla 的答案以使用二次进出缓动(更平滑一点:)。这是一个实际的示例:on jsFiddle。缓动功能在这里可用:Robert Penner's Easing functions

document.getElementsByTagName('button')[0].onclick = function () 
    scrollTo(document.body, 0, 1250);   


function scrollTo(element, to, duration) 
    var start = element.scrollTop,
        change = to - start,
        increment = 20;

    var animateScroll = function(elapsedTime)         
        elapsedTime += increment;
        var position = easeInOut(elapsedTime, start, change, duration);                        
        element.scrollTop = position; 
        if (elapsedTime < duration) 
            setTimeout(function() 
                animateScroll(elapsedTime);
            , increment);
        
    ;

    animateScroll(0);


function easeInOut(currentTime, start, change, duration) 
    currentTime /= duration / 2;
    if (currentTime < 1) 
        return change / 2 * currentTime * currentTime + start;
    
    currentTime -= 1;
    return -change / 2 * (currentTime * (currentTime - 2) - 1) + start;

【讨论】:

您的代码在 Firefox 中不起作用。有解决办法吗? @Milos 只需使用“scrollTo(document.documentElement, 0, 1250);”而不是“scrollTo(document.body, 0, 1250);”它应该可以在 Firefox 和 Chrome 中运行。 你为什么使用数学?没有数学它正在工作demo @Daniel document. documentElement 在 Chrome 中不起作用。 @bCliks,这是一种缓动方法【参考方案4】:

刚刚在下面制作了这个仅限 javascript 的解决方案。

简单用法:

EPPZScrollTo.scrollVerticalToElementById('wrapper', 0);

引擎对象(你可以摆弄过滤器、fps 值):

/**
 *
 * Created by Borbás Geri on 12/17/13
 * Copyright (c) 2013 eppz! development, LLC.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */


var EPPZScrollTo =

    /**
     * Helpers.
     */
    documentVerticalScrollPosition: function()
    
        if (self.pageYOffset) return self.pageYOffset; // Firefox, Chrome, Opera, Safari.
        if (document.documentElement && document.documentElement.scrollTop) return document.documentElement.scrollTop; // Internet Explorer 6 (standards mode).
        if (document.body.scrollTop) return document.body.scrollTop; // Internet Explorer 6, 7 and 8.
        return 0; // None of the above.
    ,

    viewportHeight: function()
     return (document.compatMode === "CSS1Compat") ? document.documentElement.clientHeight : document.body.clientHeight; ,

    documentHeight: function()
     return (document.height !== undefined) ? document.height : document.body.offsetHeight; ,

    documentMaximumScrollPosition: function()
     return this.documentHeight() - this.viewportHeight(); ,

    elementVerticalClientPositionById: function(id)
    
        var element = document.getElementById(id);
        var rectangle = element.getBoundingClientRect();
        return rectangle.top;
    ,

    /**
     * Animation tick.
     */
    scrollVerticalTickToPosition: function(currentPosition, targetPosition)
    
        var filter = 0.2;
        var fps = 60;
        var difference = parseFloat(targetPosition) - parseFloat(currentPosition);

        // Snap, then stop if arrived.
        var arrived = (Math.abs(difference) <= 0.5);
        if (arrived)
        
            // Apply target.
            scrollTo(0.0, targetPosition);
            return;
        

        // Filtered position.
        currentPosition = (parseFloat(currentPosition) * (1.0 - filter)) + (parseFloat(targetPosition) * filter);

        // Apply target.
        scrollTo(0.0, Math.round(currentPosition));

        // Schedule next tick.
        setTimeout("EPPZScrollTo.scrollVerticalTickToPosition("+currentPosition+", "+targetPosition+")", (1000 / fps));
    ,

    /**
     * For public use.
     *
     * @param id The id of the element to scroll to.
     * @param padding Top padding to apply above element.
     */
    scrollVerticalToElementById: function(id, padding)
    
        var element = document.getElementById(id);
        if (element == null)
        
            console.warn('Cannot find element with id \''+id+'\'.');
            return;
        

        var targetPosition = this.documentVerticalScrollPosition() + this.elementVerticalClientPositionById(id) - padding;
        var currentPosition = this.documentVerticalScrollPosition();

        // Clamp.
        var maximumScrollPosition = this.documentMaximumScrollPosition();
        if (targetPosition > maximumScrollPosition) targetPosition = maximumScrollPosition;

        // Start animation.
        this.scrollVerticalTickToPosition(currentPosition, targetPosition);
    
;

【讨论】:

男人,真的吗?创建这段可怕的代码就像使用火箭发射器杀死一只苍蝇。 @Killah 我真的很关心简单的用法和可读性。如果你愿意,我可以把它缩小。 :) 我的意思是那里有太多的辅助函数(为什么你需要一个使用一次的辅助函数?),还有console.warnsetTimeout中的字符串参数不适合生产代码(第二个几乎不适合任何地方,因为它基本上是eval)。 假设函数调用不是很昂贵的东西,我更喜欢将任何代码提取到命名函数而不是注释周围的所有内容。所以你(至少我)可以更好地阅读代码,客户端代码也可以是更短的 10 行。【参考方案5】:

没有 JQuery 代码,希望对你有帮助。

function TopscrollTo() 
if(window.scrollY!=0)

    setTimeout(function() 
       window.scrollTo(0,window.scrollY-30);
        TopscrollTo();
    , 100);
   

在按钮单击事件或您想要的任何其他元素/事件上调用此 TopscrollTo() 函数

【讨论】:

【参考方案6】:

我修改了@TimWolla 的代码以添加更多选项和一些运动功能。 此外,通过 document.body.scrollTopdocument.documentElement.scrollTop

添加了对跨浏览器的支持
// scroll to top
scrollTo(0, 1000);

// Element to move, time in ms to animate
function scrollTo(element, duration) 
    var e = document.documentElement;
    if(e.scrollTop===0)
        var t = e.scrollTop;
        ++e.scrollTop;
        e = t+1===e.scrollTop--?e:document.body;
    
    scrollToC(e, e.scrollTop, element, duration);


// Element to move, element or px from, element or px to, time in ms to animate
function scrollToC(element, from, to, duration) 
    if (duration <= 0) return;
    if(typeof from === "object")from=from.offsetTop;
    if(typeof to === "object")to=to.offsetTop;

    scrollToX(element, from, to, 0, 1/duration, 20, easeOutCuaic);


function scrollToX(element, xFrom, xTo, t01, speed, step, motion) 
    if (t01 < 0 || t01 > 1 || speed<= 0) 
        element.scrollTop = xTo;
        return;
    
    element.scrollTop = xFrom - (xFrom - xTo) * motion(t01);
    t01 += speed * step;

    setTimeout(function() 
        scrollToX(element, xFrom, xTo, t01, speed, step, motion);
    , step);

function easeOutCuaic(t)
    t--;
    return t*t*t+1;

http://jsfiddle.net/forestrf/tPQSv/

缩小版: http://jsfiddle.net/forestrf/tPQSv/139/

// c = element to scroll to or top position in pixels
// e = duration of the scroll in ms, time scrolling
// d = (optative) ease function. Default easeOutCuaic
function scrollTo(c,e,d)d||(d=easeOutCuaic);var a=document.documentElement;if(0===a.scrollTop)var b=a.scrollTop;++a.scrollTop;a=b+1===a.scrollTop--?a:document.bodyb=a.scrollTop;0>=e||("object"===typeof b&&(b=b.offsetTop),"object"===typeof c&&(c=c.offsetTop),function(a,b,c,f,d,e,h)function g()0>f||1<f||0>=d?a.scrollTop=c:(a.scrollTop=b-(b-c)*h(f),f+=d*e,setTimeout(g,e))g()(a,b,c,0,1/e,20,d));
function easeOutCuaic(t)
    t--;
    return t*t*t+1;

【讨论】:

第一次调用scrollToX时1 / duration有什么意义? t01 是从 0 递增到 1 的时间。如果达到 1,则滚动结束。我是 2 年前做的,我不记得所有内容了,抱歉。【参考方案7】:

看起来已经有很多解决方案了。无论如何,这是另一个,使用缓动方程..

// 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');

【讨论】:

很高兴有人在使用requestAnimationFrame 应该被选为答案。这是唯一可以跨浏览器使用的 requestAnimationFrame 与所有浏览器和某些手机不兼容,因此它不是动态解决方案,请参阅:developer.mozilla.org/en-US/docs/Web/API/window/… @SUB-HDR 在 sn-p 的顶部有一个用于 requestAnimationFrame 的 shim,它应该处理任何浏览器不兼容问题 当页面在 Firefox ***.com/questions/56396100/…987654322@上有很多图片时,动画会变得非常滞后。【参考方案8】:

我看到上述大多数/所有帖子都在搜索带有 javascript 的按钮。只要您只有一个按钮,它就可以工作。我建议在按钮内定义一个“onclick”元素。然后那个“onclick”会调用导致它滚动的函数。

如果你这样做,你可以使用多个按钮,只要按钮看起来像这样:

<button onclick="scrollTo(document.body, 0, 1250)">To the top</button>

【讨论】:

这没有动画。【参考方案9】:

这是基于上述答案的跨浏览器方法

function scrollTo(to, duration) 
    if (duration < 0) return;
    var scrollTop = document.body.scrollTop + document.documentElement.scrollTop;
    var difference = to - scrollTop;
    var perTick = difference / duration * 10;

    setTimeout(function() 
      scrollTop = scrollTop + perTick;
      document.body.scrollTop = scrollTop;
      document.documentElement.scrollTop = scrollTop;
      if (scrollTop === to) return;
      scrollTo(to, duration - 10);
    , 10);
  

【讨论】:

不错的答案!你能解释一下differenceperTick 发生了什么吗?【参考方案10】:

基于此处的一些答案,但使用一些简单的数学来使用正弦曲线进行平滑过渡:

scrollTo(element, from, to, duration, currentTime) 
       if (from <= 0)  from = 0;
       if (to <= 0)  to = 0;
       if (currentTime>=duration) return;
       let delta = to-from;
       let progress = currentTime / duration * Math.PI / 2;
       let position = delta * (Math.sin(progress));
       setTimeout(() => 
           element.scrollTop = from + position;
           this.scrollTo(element, from, to, duration, currentTime + 10);
       , 10);
   

用法:

// Smoothly scroll from current position to new position in 1/2 second.
scrollTo(element, element.scrollTop, element.scrollTop + 400, 500, 0);

附言。注意 ES6 风格

【讨论】:

【参考方案11】:

纯 JAVASCRIPT 滚动类

这是一个老问题,但我想如果你想对动画有更多的控制,我可以用一些花哨的东西和更多的选项来回答。

跨浏览器 复制/粘贴就绪解决方案(您只需要 CSS 和 JS) 3 种动画模式:["normal"|"linear"|false] 使用可用设置自定义您的动画 - 使其流畅或流畅 双击跳过动画 每下一次单击都会增加初始速度 通过向下拖动滚动条停止滚动动画 通过鼠标滚轮停止滚动动画 动画按钮在滚动时淡入淡出

这是一个纯 JS 类来为你处理滚动:

查看演示CODEPEN或进入底部并运行SINPET

// ------------------- USE EXAMPLE ---------------------
// *Set options
var options = 
  'showButtonAfter': 200, // show button after scroling down this amount of px
  'animate': "linear", // [false|normal|linear] - for false no aditional settings are needed

  'normal':  // applys only if [animate: normal] - set scroll loop distanceLeft/steps|ms
    'steps': 20, // the more steps per loop the slower animation gets
    'ms': 10 // the less ms the quicker your animation gets
  , 
  'linear':  // applys only if [animate: linear] - set scroll px|ms
    'px': 30, // the more px the quicker your animation gets
    'ms': 10 // the less ms the quicker your animation gets
  , 
;


// *Create new Scroller and run it.
var scroll = new Scroller(options);
scroll.init();

完整的类脚本 + 使用示例:

// PURE JAVASCRIPT (OOP)

function Scroller(options) 
  this.options = options;
  this.button = null;
  this.stop = false;


Scroller.prototype.constructor = Scroller;

Scroller.prototype.createButton = function() 

  this.button = document.createElement('button');
  this.button.classList.add('scroll-button');
  this.button.classList.add('scroll-button--hidden');
  this.button.textContent = "^";
  document.body.appendChild(this.button);


Scroller.prototype.init = function() 
  this.createButton();
  this.checkPosition();
  this.click();
  this.stopListener();


Scroller.prototype.scroll = function() 
  if (this.options.animate == false || this.options.animate == "false") 
    this.scrollNoAnimate();
    return;
  
  if (this.options.animate == "normal") 
    this.scrollAnimate();
    return;
  
  if (this.options.animate == "linear") 
    this.scrollAnimateLinear();
    return;
  

Scroller.prototype.scrollNoAnimate = function() 
  document.body.scrollTop = 0;
  document.documentElement.scrollTop = 0;

Scroller.prototype.scrollAnimate = function() 
  if (this.scrollTop() > 0 && this.stop == false) 
    setTimeout(function() 
      this.scrollAnimate();
      window.scrollBy(0, (-Math.abs(this.scrollTop()) / this.options.normal['steps']));
    .bind(this), (this.options.normal['ms']));
  

Scroller.prototype.scrollAnimateLinear = function() 
  if (this.scrollTop() > 0 && this.stop == false) 
    setTimeout(function() 
      this.scrollAnimateLinear();
      window.scrollBy(0, -Math.abs(this.options.linear['px']));
    .bind(this), this.options.linear['ms']);
  


Scroller.prototype.click = function() 

  this.button.addEventListener("click", function(e) 
    e.stopPropagation();
    this.scroll();
  .bind(this), false);

  this.button.addEventListener("dblclick", function(e) 
    e.stopPropagation();
    this.scrollNoAnimate();
  .bind(this), false);



Scroller.prototype.hide = function() 
  this.button.classList.add("scroll-button--hidden");


Scroller.prototype.show = function() 
  this.button.classList.remove("scroll-button--hidden");


Scroller.prototype.checkPosition = function() 
  window.addEventListener("scroll", function(e) 
    if (this.scrollTop() > this.options.showButtonAfter) 
      this.show();
     else 
      this.hide();
    
  .bind(this), false);


Scroller.prototype.stopListener = function() 

  // stop animation on slider drag
  var position = this.scrollTop();
  window.addEventListener("scroll", function(e) 
    if (this.scrollTop() > position) 
      this.stopTimeout(200);
     else 
      //...
    
    position = this.scrollTop();
  .bind(this, position), false);

  // stop animation on wheel scroll down
  window.addEventListener("wheel", function(e) 
    if (e.deltaY > 0) this.stopTimeout(200);
  .bind(this), false);


Scroller.prototype.stopTimeout = function(ms) 
  this.stop = true;
  // console.log(this.stop); //
  setTimeout(function() 
    this.stop = false;
    console.log(this.stop); //
  .bind(this), ms);


Scroller.prototype.scrollTop = function() 
  var curentScrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  return curentScrollTop;




// ------------------- USE EXAMPLE ---------------------
// *Set options
var options = 
  'showButtonAfter': 200, // show button after scroling down this amount of px
  'animate': "normal", // [false|normal|linear] - for false no aditional settings are needed

  'normal':  // applys only if [animate: normal] - set scroll loop distanceLeft/steps|ms
    'steps': 20, // the more steps per loop the slower animation gets
    'ms': 10 // the less ms the quicker your animation gets
  ,
  'linear':  // applys only if [animate: linear] - set scroll px|ms
    'px': 30, // the more px the quicker your animation gets
    'ms': 10 // the less ms the quicker your animation gets
  ,
;
// *Create new Scroller and run it.
var scroll = new Scroller(options);
scroll.init();
/* CSS */

@import url(https://fonts.googleapis.com/css?family=Open+Sans);
 body 
  font-family: 'Open Sans', sans-serif;
  font-size: 1.2rem;
  line-height: 2rem;
  height: 100%;
  position: relative;
  padding: 0 25%;

.scroll-button 
  font-size: 1.2rem;
  line-height: 2rem;
  padding: 10px;
  width: 50px;
  height: 50px;
  background: black;
  color: white;
  border-radius: 50%;
  position: fixed;
  right: 20px;
  bottom: 20px;
  visibility: visible;
  filter: alpha(opacity=50);
  filter: progid: DXImageTransform.Microsoft.Alpha(Opacity=50);
  opacity: 0.5;
  cursor: pointer;
  transition: all 1.2s;
  -webkit-transition: all 1.2s;
  -moz-transition: all 1.2s;
  -ms-transition: all 1.2s;
  -o-transition: all 1.2s;

.scroll-button:hover 
  filter: alpha(opacity=100);
  filter: progid: DXImageTransform.Microsoft.Alpha(Opacity=100);
  opacity: 1;

.scroll-button--hidden 
  filter: alpha(opacity=0);
  filter: progid: DXImageTransform.Microsoft.Alpha(Opacity=0);
  opacity: 0;
  visibility: hidden;
<!-- HTML -->

<h1>Scroll down by 200px for button to appear</h1>
<ul>
  <li>Cross-browser</li>
  <li>Copy/Paste solution</li>
  <li>3 animate modes: <b>["normal"|"linear"|false]</b></li>
  <li>Customize your aniamtion with aveilable settings - make it snapy or fluent</li>
  <li>Double click to skip animation</li>
  <li>Every next single click adds initial speed</li>
  <li>Stop scroll animation by draging down the scroll bar</li>
  <li>Stop scroll animation by mouse wheel down</li>
  <li>Animated button fade-in-out on scroll</li>
</ul>

<br />
<br />
<pre>
// ------------------- USE EXAMPLE ---------------------
// *Set options
var options = 
  'showButtonAfter': 200, // show button after scroling down this amount of px
  'animate': "normal", // [false|normal|linear] - for false no aditional settings are needed
  
  'normal':  // applys only if [animate: normal] - set scroll loop distanceLeft/steps|ms
    'steps': 20, // the more steps the slower animation gets
    'ms': 20 // the less ms the quicker your animation gets
  , 
  'linear':  // applys only if [animate: linear] - set scroll px|ms
    'px': 55, // the more px the quicker your animation gets
    'ms': 10 // the less ms the quicker your animation gets
  , 
;

// *Create new Scroller and run it.
var scroll = new Scroller(options);
scroll.init();
</pre>
<br />
<br />
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae molestiae illo nobis quo autem molestias voluptatum quam, amet ipsum debitis, iure animi illum soluta eaque qui perspiciatis harum, sequi nesciunt.</span><span>Quisquam nesciunt aspernatur a possimus pariatur enim architecto. Hic aperiam sit repellat doloremque vel est soluta et assumenda dolore, sint sapiente porro, quam impedit. Sint praesentium quas excepturi, voluptatem dicta!</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptate, porro nisi molestias minima corrupti tempore, dolorum fugiat ipsam dicta doloremque accusamus atque consequatur iusto natus, mollitia distinctio odit dolor tempora.</span><span>Perferendis a in laudantium accusantium, dolorum eius placeat velit porro similique, eum cumque veniam neque aspernatur architecto suscipit rem laboriosam voluptates laborum? Voluptates tempora necessitatibus animi nostrum quod, maxime odio.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nihil accusantium, itaque corporis repellat pariatur soluta officia perspiciatis in reprehenderit facere, incidunt saepe excepturi. Inventore atque ex illo, ipsam at deserunt.</span><span>Laborum inventore officia, perspiciatis cumque magni consequatur iste accusantium soluta, nesciunt blanditiis voluptatibus adipisci laudantium mollitia minus quia necessitatibus voluptates. Minima unde quos impedit necessitatibus aspernatur minus maiores ipsa eligendi!</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptate nesciunt, explicabo similique, quo maxime modi, aliquid, voluptatibus repellendus dolorum placeat mollitia ea dicta quia laboriosam alias dignissimos ipsam tenetur. Nulla.</span><span>Vel maiores necessitatibus odio voluptate debitis, error in accusamus nulla, eum, nemo et ea commodi. Autem numquam at, consequatur temporibus. Mollitia placeat nobis blanditiis impedit distinctio! Ad, incidunt fugiat sed.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam voluptatum, odio quam omnis iste laudantium, itaque architecto, eos ullam debitis delectus sapiente nemo autem reprehenderit. Dolorem quidem facere ipsam! Nisi.</span><span>Vitae quaerat modi voluptatibus ratione numquam? Sapiente aliquid officia pariatur quibusdam aliquam id expedita non recusandae, cumque deserunt asperiores. Corrupti et doloribus aspernatur ipsum asperiores, ipsa unde corporis commodi reiciendis?</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima adipisci minus iste, nesciunt itaque quisquam quidem voluptatum assumenda rerum aliquid, excepturi voluptatem tempora. Possimus ratione alias a error vel, rem.</span><span>Officia esse error accusantium veritatis ad, et sit animi? Recusandae mollitia odit tenetur ad cumque maiores eligendi blanditiis nobis hic tempora obcaecati consequatur commodi totam, debitis, veniam, ducimus molestias ut.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Obcaecati quibusdam, tempora cupiditate quaerat tempore ullam delectus voluptates optio eum placeat provident consequatur iure reprehenderit vero quae sapiente architecto earum nemo.</span><span>Quis molestias sint fuga doloribus, necessitatibus nulla. Esse ipsa, itaque asperiores. Tempora a sequi nobis cumque incidunt aspernatur, pariatur rem voluptatibus. Atque veniam magnam, ea laudantium ipsum reprehenderit sapiente repellendus.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima, pariatur at explicabo aliquid repudiandae vero eum quasi totam voluptates iusto unde ad repellendus ipsam et voluptatem hic adipisci! Vero, nobis!</span><span>Consequatur eligendi quo quas omnis architecto dolorum aperiam doloremque labore, explicabo enim incidunt vitae saepe, quod soluta illo odit provident amet beatae quasi animi. Similique nostrum molestiae animi corrupti qui?</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Molestias quis, tempora laborum incidunt qui fuga adipisci doloremque iusto commodi vitae est, nemo iure placeat ut sit optio, consequuntur voluptas impedit.</span><span>Eos officiis, hic esse unde eaque, aut tenetur voluptate quam sint vel exercitationem totam dolor odio soluta illo praesentium non corrupti! Consequuntur velit, mollitia excepturi. Minus, veniam accusantium! Aliquam, ea!</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reprehenderit quis reiciendis veritatis expedita velit vitae amet magni sunt rerum in blanditiis aut tempore quia fugiat, voluptates officia quaerat quam id.</span><span>Sapiente tempore repudiandae, quae doloremque ullam odio quia ea! Impedit atque, ipsa consequatur quis obcaecati voluptas necessitatibus, cupiditate sunt amet ab modi illum inventore, a dolor enim similique architecto est!</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Itaque non aliquam, sit illo quas deserunt esse nobis reprehenderit quidem fuga beatae eligendi reiciendis omnis qui repellat velit earum blanditiis possimus.</span><span>Provident aspernatur ducimus, illum beatae debitis vitae non dolorum rem officia nostrum natus accusantium perspiciatis ad soluta maiores praesentium eveniet qui hic quis at quaerat ea perferendis. Ut, aut, natus.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ratione corrupti quibusdam, sed hic veniam. Perspiciatis ex, quod architecto natus autem totam at commodi excepturi maxime pariatur corporis, veritatis vero, praesentium.</span><span>Nesciunt suscipit, nobis eos perferendis ex quaerat inventore nihil qui magnam saepe rerum velit reiciendis ipsam deleniti ducimus eligendi odio eius minima vero, nisi voluptates amet eaque, iste, labore laudantium.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illo, voluptas accusantium ad omnis velit distinctio! Adipisci magnam nihil nostrum molestiae rem dolores, ut ad nemo, dolor quos itaque maiores quaerat!</span><span>Quia ad suscipit reprehenderit vitae inventore eius non culpa maiores omnis sit obcaecati vel placeat quibusdam, ipsa exercitationem nam odit, magni nobis. Quam quas, accusamus expedita molestiae asperiores eaque ex?</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rerum explicabo doloribus nihil iusto quasi vel expedita dignissimos amet mollitia, temporibus aut atque architecto assumenda dolorum nam velit deserunt totam numquam.</span><span>Ab perferendis labore, quae. Quidem architecto quo officia deserunt ea doloribus libero molestias id nisi perferendis eum porro, quibusdam! Odit aliquid placeat rem aut officia minus sit esse eos obcaecati!</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eligendi nostrum repellendus placeat, unde aperiam. Fuga, voluptas, minima. Debitis nemo ducimus itaque laboriosam error quaerat reprehenderit quo animi incidunt. Nulla, quis!</span><span>Explicabo assumenda dicta ratione? Tempora commodi asperiores, explicabo doloremque eius quia impedit possimus architecto sit nemo odio eum fuga minima dolor iste mollitia sequi dolorem perspiciatis unde quisquam laborum soluta.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Veniam officia corporis, reiciendis laudantium, voluptate voluptates necessitatibus assumenda, delectus quisquam velit deserunt! Reprehenderit, vel quaerat accusantium nesciunt libero animi. Sequi, eveniet?</span><span>Animi natus pariatur porro, alias, veniam aut est tempora adipisci molestias harum modi cumque assumenda enim! Expedita eveniet autem illum rerum nostrum ipsum alias neque aut, dolorum impedit pariatur non?</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis aliquid rerum, odio veniam ipsam ad officia quos repellat ex aperiam voluptatum optio est animi possimus minus. Sapiente voluptates amet dolorem.</span><span>Illo necessitatibus similique asperiores inventore ut cumque nihil assumenda debitis explicabo rerum, dolorum molestiae culpa accusantium. Nisi doloremque optio provident blanditiis, eum ipsam asperiores, consequatur aliquam vel sit mollitia sunt.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Enim, totam harum perferendis. Minus ea perferendis laboriosam, iste, qui corrupti, quas veritatis omnis officiis animi fuga perspiciatis impedit! Error, harum, voluptas.</span><span>Omnis laborum, cum mollitia facilis ipsa unde distinctio maxime nesciunt illum perspiciatis ut officiis, eligendi numquam dolorem quod modi ipsam est rerum perferendis repellendus totam. Maxime excepturi culpa alias labore.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Impedit deleniti, odit sit consequatur dolorum omnis repellendus, alias vel ullam numquam. Nostrum obcaecati hic, possimus delectus nam atque aliquid explicabo cum.</span><span>Explicabo tenetur minima consequatur, aliquam, laudantium non consequuntur facilis sint, suscipit debitis ex atque mollitia magni quod repellat ratione dolorum excepturi molestiae cumque iusto eos unde? Voluptatum dolores, porro provident!</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. At laboriosam fuga aperiam eveniet, obcaecati esse, nulla porro iure molestiae praesentium sint fugiat ea voluptate suscipit voluptates mollitia, voluptatibus. Autem, non.</span><span>Numquam velit culpa tempora ratione ipsum minus modi in? Nisi reiciendis, voluptate voluptatem maxime repellat quae odio, repellendus aliquid laborum dolorem. Labore, fuga ea minima explicabo quae voluptatum necessitatibus, similique.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quasi, rerum dolorum nemo error fugiat ut, modi, architecto libero maxime laborum repellendus doloribus neque aperiam adipisci quaerat obcaecati deserunt consequuntur amet!</span><span>Sint, assumenda nisi obcaecati doloremque iste. Perspiciatis accusantium, distinctio impedit cum esse recusandae sunt. Officiis culpa dolore eius, doloribus natus, dolorum excepturi vitae fugiat ullam provident harum! Suscipit, assumenda, harum.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit, nihil tenetur tempore eligendi qui nesciunt consequatur delectus accusantium consectetur ipsa, nulla doloribus dolores rerum corporis, laborum, laboriosam hic mollitia repellat.</span><span>Ab deleniti vitae blanditiis quod tenetur! Voluptatem temporibus ab eaque quis? Quis odio aliquid harum temporibus totam, ipsa eius iusto fugiat enim in, quibusdam molestiae aliquam consequatur nulla, consequuntur sint.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illum odit praesentium quos, earum nesciunt laudantium illo tempora eligendi, porro doloremque mollitia neque aperiam inventore nam maxime dolor labore aspernatur molestias.</span><span>Voluptatibus provident hic cupiditate placeat, ut reprehenderit nisi eum, dolores ad sed quis. Doloribus molestiae, quae rem odit expedita soluta, facilis animi corporis velit ut in, recusandae harum laboriosam veritatis.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Incidunt repudiandae molestias magnam delectus veritatis labore, corporis dicta officia quos, ad corrupti odit! Ad hic officia maxime eveniet consectetur similique adipisci!</span><span>Quia at, nesciunt aliquid delectus ex alias voluptas maxime hic esse. Incidunt, laborum quos mollitia dolores et! Voluptas commodi asperiores, fugit quidem quis corporis, a eaque, animi, autem deserunt repellendus.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi quas, voluptas hic minima inventore optio, id quidem placeat necessitatibus omnis voluptatibus vitae mollitia tempora consequuntur consequatur, illo facilis accusamus illum.</span><span>Voluptates consequuntur ipsam odit. Eius quis ipsam vitae, nihil molestias perferendis corporis recusandae consequatur vero iure blanditiis quas adipisci quos voluptatem rem illo voluptate. Eveniet officiis iure sit laborum veniam.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Suscipit a quis cumque nostrum quisquam molestiae pariatur, asperiores natus necessitatibus adipisci illum cupiditate nam vero, tempora excepturi laborum, earum. Voluptates, nobis.</span><span>Pariatur suscipit, hic blanditiis libero, iusto, quam cupiditate nam error id asperiores repellat ab consequatur vitae ipsa voluptatem totam magni reiciendis expedita maxime dolor! Minus explicabo quas, laborum ab omnis!</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore qui ad assumenda placeat optio illo molestias corporis dolorum cum. Doloribus eius autem obcaecati minima, asperiores iure dignissimos ducimus suscipit dolorem.</span><span>Blanditiis earum accusamus eaque temporibus necessitatibus voluptatum dolorem enim debitis inventore assumenda quae error perspiciatis aut, nulla delectus quam ipsa sapiente ea aliquam laboriosam repudiandae. Nesciunt praesentium, beatae eos quasi!</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cupiditate dicta voluptate impedit? Ad voluptatum dicta earum perferendis asperiores. Dolore distinctio modi expedita consequatur provident perspiciatis neque totam rerum placeat quas.</span><span>Eveniet optio est possimus iste accusantium ipsum illum. Maiores saepe repudiandae facere, delectus iure dolorem vitae nihil pariatur minima, reprehenderit eligendi dolore impedit, nisi doloribus quidem similique. Optio, delectus, minus.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iste ex molestiae architecto enim nihil tempore, atque consequuntur doloribus recusandae sed consequatur veniam quos, in consectetur perspiciatis magni nostrum ab voluptates.</span><span>Nisi quos mollitia quis in maiores asperiores labore deserunt! Voluptate voluptas adipisci qui hic officia molestias, laborum necessitatibus sint nam vel minus incidunt perspiciatis recusandae sunt, rerum suscipit doloremque possimus!</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. At nihil perferendis quae quidem facilis aliquid pariatur possimus hic asperiores, recusandae exercitationem adipisci atque laborum, delectus, odit ab reprehenderit distinctio dolor.</span><span>Non excepturi quos aspernatur repudiandae laboriosam, unde molestias, totam, sapiente harum accusamus delectus laborum ipsam velit amet nisi! Consectetur aliquam provident voluptatibus saepe repudiandae eveniet laborum beatae, animi, voluptate dolores.</span></p>
<p><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cumque magni, eum ipsa, veritatis facere voluptatem dolorum nobis neque minus debitis asperiores iste. Pariatur sequi quam, tempora. Dignissimos, esse similique tempora.</span><span>Ex delectus excepturi autem sunt, nemo repudiandae, recusandae nostrum accusantium nobis temporibus magnam eligendi similique veritatis deleniti, eaque blanditiis possimus at! Repellat alias laboriosam ipsum commodi dolorem, corporis dolore suscipit!</span></p>

【讨论】:

如果你仔细看看,这很简单。也许是 OOP 让它看起来比实际上要复杂一些。其他 sn-ps 将不包括中断滚动功能。所以我发布了一些更完整的东西。如果您不关心这一点,那么我的解决方案可以满足您的需求。为了让它在 FF 和 IE 中工作,你只需要为我认为的 CSS 添加前缀。我会修复它以防其他人要求这样做。我添加 CSS 是因为我想让它成为“复制/粘贴”解决方案。我认为这不会比这更容易:-)。 好的,这不是前缀问题 :) 但无论如何我都会修复它。 问题已解决。它现在可以在 IE、FF 和 Chrome 中运行...这里发生了什么:“document.documentElement.scrollTop”适用于 Firefox 和 IE,但不适用于 Chrome,“document.body.scrollTop”适用于 Chrome,但不适用于 Firefox,而不适用在 IE 中。为了解决这个问题,新方法 [scrollTop()] 被实现到类原型。新方法从它工作的浏览器返回值: // varcurentScrollTop = document.documentElement.scrollTop || document.body.scrollTop; // 返回curentScrollTop; 修复了另一个 IE 错误。 classList.add('class1, class2');只会应用 class1,class2 将被忽略,.修复:classList.add('class1'); classList.add('class2');现在按钮在加载 IE 时隐藏。【参考方案12】:

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

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

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

【讨论】:

【参考方案13】:
window.scroll(top: 0, left: 0, behavior: 'smooth' );

从一篇关于 Smooth Scrolling 的文章中得到它。

如果需要,有一些polyfills 可用。

【讨论】:

几乎被否决了,因为我认为这是一个 jQuery 解决方案。那篇文章分类混乱!另外,我想指出scrollIntoView(behavior: 'smooth') 也存在,并且可以为人们解决此类问题提供帮助。 这会在最新的 Chrome 中引发错误 Uncaught TypeError: Failed to execute 'scroll' on 'Window': No function was found that matched the signature provided. @Sgnl 可以确认此问题现已修复。旧的 Chrome 更新破坏了一些东西 :) 我不知道为什么这没有更多的票,一个简单的滚动到顶部没有100000行代码!谢谢! 此答案必须标记为已接受。一种不使用任何自定义转换函数的内置方法,为什么不呢!?谢谢!【参考方案14】:

另一种方法是使用window.scrollBy

JSFiddle

function scroll(pxPerFrame, duration) 
        if (!pxPerFrame || !duration) return;
        const end = new Date().getTime() + duration;
        step(); 

        function step() 
          window.scrollBy(0, pxPerFrame);
          if (new Date().getTime() < end) 
            window.setTimeout(step, 1000 / 60);
           else 
            console.log('done scrolling'); 
          
        
      
body 
  width: 200px;
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>
<button onclick="scroll(-5, 3000)">
scroll(-5, 3000)
</button>
</p>

【讨论】:

【参考方案15】:

改编自this answer:

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”。

【讨论】:

【参考方案16】:

我选择了@akai 版本的@timwolla 答案并添加了 stopAnimation 函数作为回报,所以在开始新动画之前,可以停止旧动画。

if ( this.stopAnimation )
    this.stopAnimation()

    this.stopAnimation = scrollTo( el, scrollDestination, 300 )


// definitions

function scrollTo(element, to, duration) 
    var start = element.scrollTop,
        change = to - start,
        increment = 20,
        timeOut;

    var animateScroll = function(elapsedTime)         
        elapsedTime += increment;
        var position = easeInOut(elapsedTime, start, change, duration);                        
        element.scrollTop = position; 
        if (elapsedTime < duration) 
            timeOut = setTimeout(function() 
                animateScroll(elapsedTime);
            , increment);
        
    ;

    animateScroll(0);

    return stopAnimation

    function stopAnimation() 
        clearTimeout( timeOut )
    


function easeInOut(currentTime, start, change, duration) 
    currentTime /= duration / 2;
    if (currentTime < 1) 
        return change / 2 * currentTime * currentTime + start;
    
    currentTime -= 1;
    return -change / 2 * (currentTime * (currentTime - 2) - 1) + start;

【讨论】:

【参考方案17】:

实际上有一种纯 javascript 方法可以在不使用 setTimeoutrequestAnimationFrame 或 jQuery 的情况下完成此操作。

简单来说就是在scrollView中找到你想要滚动到的元素,使用scrollIntoView

el.scrollIntoView(behavior:"smooth");

这是plunkr。

【讨论】:

最佳答案:一行代码,最短且有效;) 请注意,传递scrollIntoViewOption 不具有跨浏览器支持。 developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView【参考方案18】:

使用此解决方案

animate(document.documentElement, 'scrollTop', 0, 200);

谢谢

【讨论】:

不幸的是,这似乎不是很精通跨浏览器。 :( @LucasMorgan 你只需要为“document.documentElemen”找到正确的 dom 元素,就像任何适合你的一样 除非在窗口范围内有animate() 函数...我想你误会了。许多浏览器无法识别Element.animate() 函数。见developer.mozilla.org/en-US/docs/Web/API/Element/animate 是的,我误会了。你说的是一个 jquery 函数。我假设您不会提出 jquery,因为问题要求没有 jquery。我的错!【参考方案19】:

没有人提到CSS属性scroll-behavior

CSS

html 
  scroll-behavior: smooth;

JS

window.scrollTo(0,0)

【讨论】:

这太棒了!并非所有浏览器都支持,但没关系,因为它可以很好地回退。 天哪,我这辈子都去哪儿了? 向上,向上,向上,向上! :)【参考方案20】:

线性滚动动画到底部。纯 JS,没有 JQuery。也许我的解决方案会对某人有所帮助。

let action_count = 8;
let speed_ms = 15;
let objDiv = document.getElementsByClassName('js_y5_area3').item(0);

let scroll_height = objDiv.scrollHeight;
let window_height = objDiv.offsetHeight;

let scroll_top = objDiv.scrollTop;
let need_scroll_top = scroll_height - window_height;

if (scroll_top < need_scroll_top)

    let step = Math.ceil((need_scroll_top - scroll_top) / action_count);

    let scrollInterval = setInterval(function()
    
        scroll_top += step;
        objDiv.scrollTop = scroll_top;

        if (scroll_top >= need_scroll_top)
        
            clearInterval(scrollInterval);
        

    , speed_ms);

您可以更改变量action_countspeed_ms 以根据您的喜好配置滚动动画。

【讨论】:

【参考方案21】:

JS 没有 jQuery 的解决方案。

element.onclick = () => window.scrollTo( top: 0, behavior: 'smooth' )

【讨论】:

以上是关于跨浏览器 JavaScript(不是 jQuery...)滚动到顶部动画的主要内容,如果未能解决你的问题,请参考以下文章

跨浏览器窗口大小调整事件 - JavaScript / jQuery

跨浏览器实现placeholder效果的jQuery插件

jQuery(javascript)无法跨域,怎么解决?是想获取iframe的框架里面的东西!!

独立的跨浏览器库来处理 location.hash

js跨浏览器复制: ZeroClipboard

为什么原生 JavaScript 开发越来越多受欢迎?是否应该跟风用原生JavaScript代替 jQuery等库?