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

IT技术 javascript
2021-02-05 14:04:02

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

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

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

6个回答
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: body{height:100%;})。使用此概念的工作演示:jsfiddle.net/S5ALP/1
2021-03-14 14:04:02
只是抛出这个片段在 chrome 版本 69.0.3497.100 上不起作用,这是截至今天的最新版本。
2021-03-14 14:04:02
@RobW 您的添加在 Google Chrome @ Ubuntu Linux 中不起作用
2021-03-16 14:04:02
修改它以使用top.window.scroll(0, value)而不是element.scrollTop = value让它在 Chrome 和 Firefox (Ubuntu) 中工作。:)
2021-03-23 14:04:02
它在 Firefox 9.0、Ubuntu 中也可以:)。您的代码在 Firefox 中失败,但在 Chrome 中有效,我的代码在 Chrome 中失败,但在 FF 中有效。
2021-04-09 14:04:02

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

// 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');
应该投票并选择作为答案。这是唯一一个跨浏览器工作的
2021-03-11 14:04:02
requestAnimationFrame与某些手机的所有浏览器不兼容,因此它不是动态解决方案,请参阅:developer.mozilla.org/en-US/docs/Web/API/window/...
2021-04-04 14:04:02
@SUB-HDR 在代码段的顶部有一个 shim 可以解决requestAnimationFrame任何浏览器不兼容问题
2021-04-05 14:04:02
当一个页面在 Firefox stackoverflow.com/questions/56396100/上有一个包含大量图像的部分时,动画变得非常滞后。
2021-04-08 14:04:02
很高兴有人在使用 requestAnimationFrame
2021-04-10 14:04:02
window.scroll({top: 0, left: 0, behavior: 'smooth' });

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

如果需要,可以使用一些polyfill

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

我修改了 TimWolla 的答案以使用二次进出缓动(更平滑一点:)。这是一个实际示例:在 jsFiddle 上缓动函数在此处可用:Robert Penner 的缓动函数

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;
}
@bCliks,这是一种缓动方法
2021-03-15 14:04:02
您的代码在 Firefox 中不起作用。有解决方案吗?
2021-03-27 14:04:02
@Danieldocument. documentElement在 Chrome 中不起作用。
2021-04-01 14:04:02
@Milos 只需使用“scrollTo(document.documentElement, 0, 1250);” 而不是“scrollTo(document.body, 0, 1250);” 它应该适用于 Firefox 和 Chrome。
2021-04-03 14:04:02
你为什么使用数学?没有数学它是工作演示
2021-04-07 14:04:02

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

function TopscrollTo() {
if(window.scrollY!=0)
{
    setTimeout(function() {
       window.scrollTo(0,window.scrollY-30);
        TopscrollTo();
    }, 100);
   }
}

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