平滑滚动到页面顶部

101

我已经搜索了几个小时了,但还是没有找到解决方案。我希望页面能够平稳滚动到顶部。我已经使用一个附加到我的网站的 .js 文件,实现了在页面上独立锚点处的平滑滚动,但是我无法使用一个锚点来实现回到页面顶部,因为我使用的是一个免费托管站点提供的模板,内置页建设工具不允许我进行在 body 区域之上的编辑。

这里 是我找到平稳滚动效果的地方。我一直在尝试设置“平稳滚动至没有 jQuery 插件的元素”,但是明显排列无从下手,尝试次数无数次。我也试过 window.scrollTo(0, 0);,但它会瞬间滚动到顶部。谢谢!

此外:http://jsfiddle.net/WFd3V/ - 代码可能会是标签 class="smoothScroll" ,因为我的另一个元素使用了这个类名,但我不知道如何与 href="javascript:window.scrollTo(0,0);" 等混合,或者其他任何可以将页面滚动到顶部而不使用锚点的方法。


请查看我在使用纯JS实现平滑滚动的答案。 - surfmuggle
7
最简单的翻译是:onclick="window.scrollTo({ top: 0, behavior: 'smooth' });" → 点击时,窗口滚动到顶部且平滑。 - vukan
15个回答

203

我认为最简单的解决方案是:

window.scrollTo({top: 0, behavior: 'smooth'});

如果你想要即时滚动,请使用以下代码:

window.scrollTo({top: 0});

可以用作函数:

// Scroll To Top

function scrollToTop() {

window.scrollTo({top: 0, behavior: 'smooth'});

}

或作为一个onclick处理程序:

<button onclick='window.scrollTo({top: 0, behavior: "smooth"});'>Scroll to Top</button>

1
不是所有的浏览器都支持此功能。IE 11及以下版本不支持,Safari或Safari iOS也不支持。请查看完整列表:https://caniuse.com/#feat=css-scroll-behavior - tomastley
1
这在Chrome上也不起作用。它会触发一个错误,提示ScrollTo需要2个参数,但只传递了1个参数。我使用jQuery进行了修复:$('html, body').animate({scrollTop:0},'50'); - Ivica Pesovski
2
@IvicaPesovski 你可能没有将参数放在对象中。scrollTo只需要一个参数,可以是数字或对象。如果您选择传递对象,则可以指定behavior。这个解决方案在Chrome / Electron上对我很有效。 - Martin Braun

85

这是用ES6实现的我的提案

const scrollToTop = () => {
  const c = document.documentElement.scrollTop || document.body.scrollTop;
  if (c > 0) {
    window.requestAnimationFrame(scrollToTop);
    window.scrollTo(0, c - c / 8);
  }
};
scrollToTop();

小贴士:若要使滚动速度变慢,可增加硬编码数字8。数字越大,则滚动越平稳/缓慢。


很好的解决方案,谢谢。但在IE11中,scrollTop值不能低于8/2,如果您再次向下滚动,它会不断向上滚动。我做了一些更改并添加了这些行:const smoothness = 8; let val = s - s / smoothness; if (val < smoothness) val = 0; window.scrollTo(0, val);问题已经解决,但是由于val=0;,它有一点跳动效果。 - fatihsolhan
脚本带有很好的效果,但与CSS规则scroll-behavior: smooth冲突,必须在脚本执行期间禁用CSS规则。 - Olivier C
在IE中,解决方案并没有像@Solhan所说的那样正常工作。由Sohan提供的解决方案对我也没有用。是否有其他解决方案可以在IE中正常工作? - Akanksha Mohanty
最干净的解决方案是使用 window.scrollTo({ top: 0, behavior: 'smooth' }) 并添加 smoothscroll-polyfill @AkankshaMohanty - fatihsolhan

28
window.scroll({top: 0, behavior: "smooth"})

只需使用这段代码,它就可以完美地工作,你可以将其包装成一个方法或事件。


12

仅使用纯JavaScript

var t1 = 0;
window.onscroll = scroll1;

function scroll1() {
  var toTop = document.getElementById('toTop');
  window.scrollY > 0 ? toTop.style.display = 'Block' : toTop.style.display = 'none';
}

function abcd() {
  var y1 = window.scrollY;
  y1 = y1 - 1000;
  window.scrollTo(0, y1);
  if (y1 > 0) {
    t1 = setTimeout("abcd()", 100);
  } else {
    clearTimeout(t1);
  }
}
#toTop {
  display: block;
  position: fixed;
  bottom: 20px;
  right: 20px;
  font-size: 48px;
}

#toTop {
  transition: all 0.5s ease 0s;
  -moz-transition: all 0.5s ease 0s;
  -webkit-transition: all 0.5s ease 0s;
  -o-transition: all 0.5s ease 0s;
  opacity: 0.5;
  display: none;
  cursor: pointer;
}

#toTop:hover {
  opacity: 1;
}
<p>your text here</p>
<img id="toTop" src="http://via.placeholder.com/50x50" onclick="abcd()" title="Go To Top">


1
这太棒了。 - hemnath mouli
1
@hemnathmouli 谢谢 - Nikhil sHETH
似乎对我无效。已经添加了文本到“此处输入文本”部分。按钮会将您跳转回顶部。 - user2840467
@user2840467,它运行良好。我在Chrome和Mozilla中进行了检查。您能否详细描述一下您的问题。 - Nikhil sHETH

6

这个问题已经过去了一段时间。

现在不仅可以在window.scroll函数中指定数字,还可以传递一个具有三个属性的对象:top、left和behavior。因此,如果我们想要使用原生JavaScript进行平滑的向上滚动,我们可以像这样做:

let button = document.querySelector('button-id');
let options = {top: 0, left: 0, behavior: 'smooth'}; // left and top are coordinates
button.addEventListener('click', () => { window.scroll(options) });

https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll


太棒了!谢谢!! - William

6

嗯,评论功能对我来说无法开启,

请尝试这样做。

$(document).ready(function(){
    $("#top").hide();
    $(function toTop() {
        $(window).scroll(function () {
            if ($(this).scrollTop() > 100) {
                $('#top').fadeIn();
            } else {
                $('#top').fadeOut();
            }
        });

        $('#top').click(function () {
            $('body,html').animate({
                scrollTop: 0
            }, 800);
            return false;
        });
    });         
            
            
    
    });
#top {
  float:right;
  width:39px;
  margin-top:-35px; 
}
#top {
    transition: all 0.5s ease 0s;
    -moz-transition: all 0.5s ease 0s;
    -webkit-transition: all 0.5s ease 0s;
    -o-transition: all 0.5s ease 0s;
    opacity: 0.5;
    display:none;
    cursor: pointer;
}
#top:hover {
    opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
<div id="top" onclick="toTop()"><img src="to_top.png" alt="no pic "/> klick to top</div>


2
欢迎来到Stack Overflow!请考虑编辑您的帖子,添加更多关于代码的解释以及为什么它可以解决问题的说明。一个主要只包含代码的答案(即使它是有效的)通常不会帮助OP理解他们的问题。同时建议如果只是猜测就不要发布答案。一个好的答案将有一个合理的原因,为什么它可以解决OP的问题。 - SuperBiasedMan
2
好的,这个函数可以平滑地向页面顶部滚动。 - BitDEVil2K16

5

您应该开始使用jQuery或其他JavaScript库。它比JavaScript更容易,而且您可以将其用作大多数JavaScript的速记,而不是使用实际的冗长JavaScript。

简单地说,在您的<head>中放置<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>(或任何最新的Google CDN:https://developers.google.com/speed/libraries/devguide#jquery)。

然后,在您的event代码内(如果您使用jQuery,则更容易:对于按钮,请使用$.click(),对于复选框、选择器、收音机,请使用$.change()),将来自第二个链接的代码放置得更像:

$('#theIDofTheButtonThatTriggersThisAnimation').click(function(){
    $('#theIDofTheElementYouWantToSmoothlyScroll').animate({
        scrollTop: 0
    }, 2000);
});

然而,如果你要做动画效果,我建议你学习一些基本的CSS属性,比如position:absoluteposition:relative,以避免让自己发疯。
由于你的代码与现在使用的CSS和jQuery非常不标准,所以我还不太确定发生了什么。我建议你将其简化以便更好地理解概念。对于你的例子,你应该参考我学习动画的例子: https://dev59.com/tWjWa4cB1Zd3GeqPtbgh#12906254 我认为你试图通过$.click()上下移动文本。在我的答案中,它向左右滑动。你可以通过使用CSS的top属性而不是left轻松改变其上下格式。
一旦你弄清楚如何上下移动整个
,你可以创建一个relative容器来容纳所有内容absolute div,并通过设置它们的top循环操作所有内容div。这里有一个关于absoluterelative的快速入门指南: http://css-tricks.com/absolute-positioning-inside-relative-positioning/ 我所有的动画都有relative容器和absolute内容。这是我制作自定义网格视图插件的方式,它可以立即浏览整个数据库。
此外,在制作动画时,没有
使用过度。试图让一个
完成所有工作是一场噩梦。
试着看看能否将我的fiddle重新格式化成一个垂直滑出。一旦你做到了这一点,稍微研究一下absoluterelative。如果你有任何问题,请再问一个问题。
改变你的思考方式,你就会开始飞快地编写这种类型的代码。

哦,我撤回了,我意识到它还链接到一个元素,这可能需要一个锚点。 - user2267388
4
如果您已经拥有jQuery,那么只需执行 $("body").animate({scrollTop:0}); 就可以了。 - peirix
对于造成的混淆我感到抱歉,不应该将菜单栏与其一起发布,因为它也有自己的CSS和Java代码。在我的fiddle中,唯一重要的是两个<script src>和<a class="smoothScroll">。也许我应该开一个新的问题页面。 - user2267388
我找到了另一种方法,就像你说的那样,我只需要从另一个角度来看待它,意外地发现了修复页面上另一个具有类似问题的元素的想法。幸运的是,我仅使用<a name>标签将我的页面链接到单独的锚点,视图会平滑滚动到该锚点,而我用来解决无法编码到页面顶部的问题的代码是相对像素重定位器:<a name="home" style="position:relative; top:-524px;">。也许这不是我最初的目标,但我想它比完美更好。祝大家好运,谢谢。 - user2267388
@user2267388,你现在走在正确的路上。使用这些简单技巧,你的页面将变得更加生动,而且你还可以写更少的代码。祝你好运!(别忘了检查是否正确) - user1382306
显示剩余3条评论

5

您可以简单地使用

// When the user scrolls down 20px from the top of the document, show the button
window.onscroll = function() {scrollFunction()};

function scrollFunction() {
    if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
        document.getElementById("gotoTop").style.display = "block";
    } else {
        document.getElementById("gotoTop").style.display = "none";
    }
   
}

// When the user clicks on the button, scroll to the top of the document
function topFunction() {
 
     $('html, body').animate({scrollTop:0}, 'slow');
}
body {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 20px;
}

#gotoTop {
  display: none;
  position: fixed;
  bottom: 20px;
  right: 30px;
  z-index: 99;
  font-size: 18px;
  border: none;
  outline: none;
  background-color: red;
  color: white;
  cursor: pointer;
  padding: 15px;
  border-radius: 4px;
}

#gotoTop:hover {
  background-color: #555;
}
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>

<button onclick="topFunction()" id="gotoTop" title="Go to top">Top</button>

<div style="background-color:black;color:white;padding:30px">Scroll Down</div>
<div style="background-color:lightgrey;padding:30px 30px 2500px">This example demonstrates how to create a "scroll to top" button that becomes visible when the user starts to scroll the page.</div>


4

使用jQuery的优雅简单解决方案。

<script>
    function call() {
        var body = $("html, body");
        body.stop().animate({scrollTop:0}, 500, 'swing', function() {
        });
    }
</script>

在你的HTML中: <div onclick="call()"><img src="../img/arrow-up@2x.png"></div> 这个代码片段表示一个带有箭头图标的div元素,并在点击时调用名为“call()”函数。

3

如果您想了解更全面的平滑滚动方法列表,请查看我的答案这里


为了在精确的时间内滚动到特定的位置,可以使用window.requestAnimationFrame,每次计算适当的当前位置。如果不支持requestAnimationFrame,可以使用setTimeout以类似的效果进行操作。要滚动到页面顶部,请使用以下函数,并将位置设置为0
/*
   @param pos: the y-position to scroll to (in pixels)
   @param time: the exact amount of time the scrolling will take (in milliseconds)
*/
function scrollToSmoothly(pos, time) {
    var currentPos = window.pageYOffset;
    var start = null;
    if(time == null) time = 500;
    pos = +pos, time = +time;
    window.requestAnimationFrame(function step(currentTime) {
        start = !start ? currentTime : start;
        var progress = currentTime - start;
        if (currentPos < pos) {
            window.scrollTo(0, ((pos - currentPos) * progress / time) + currentPos);
        } else {
            window.scrollTo(0, currentPos - ((currentPos - pos) * progress / time));
        }
        if (progress < time) {
            window.requestAnimationFrame(step);
        } else {
            window.scrollTo(0, pos);
        }
    });
}

function scrollToSmoothly(pos, time) {
    var currentPos = window.pageYOffset;
    var start = null;
    if(time == null) time = 500;
    pos = +pos, time = +time;
    window.requestAnimationFrame(function step(currentTime) {
        start = !start ? currentTime : start;
        var progress = currentTime - start;
        if (currentPos < pos) {
            window.scrollTo(0, ((pos - currentPos) * progress / time) + currentPos);
        } else {
            window.scrollTo(0, currentPos - ((currentPos - pos) * progress / time));
        }
        if (progress < time) {
            window.requestAnimationFrame(step);
        } else {
            window.scrollTo(0, pos);
        }
    });
}

window.scrollTo(0, 2000);
document.querySelector('button').addEventListener('click', function(e){
  scrollToSmoothly(0, 700);
});
<button style="margin: 2000px 0;">Smooth scroll to top</button>

SmoothScroll.js库也可以使用,它处理更复杂的情况,例如平滑地垂直和水平滚动,在其他容器元素内滚动,不同的缓动行为,相对于当前位置滚动等等。

smoothScroll({yPos: 'start', duration: 700});
// or
smoothScroll({yPos: 0, duration: 700});

window.scrollTo(0, 2000);
document.querySelector('button').addEventListener('click', function(e){
  smoothScroll({yPos: 'start', duration: 700});
});
<script src="https://cdn.jsdelivr.net/gh/LieutenantPeacock/SmoothScroll@1.2.0/src/smoothscroll.min.js" integrity="sha384-UdJHYJK9eDBy7vML0TvJGlCpvrJhCuOPGTc7tHbA+jHEgCgjWpPbmMvmd/2bzdXU" crossorigin="anonymous"></script>
<button style="margin: 2000px 0;">Smooth scroll to top</button>

另外,您可以将选项对象传递给 window.scroll,并将行为设置为平滑滚动到特定的 x 和 y 位置,或者使用 window.scrollBy 从当前位置滚动一定量:

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

window.scrollTo(0, 2000);
document.querySelector('button').addEventListener('click', function(e){
  window.scroll({top: 0, left: 0, behavior: 'smooth'});
});
<button style="margin: 2000px 0;">Smooth scroll to top</button>

现代浏览器支持scroll-behavior CSS属性, 可以用于使文档中的滚动平滑(无需使用JavaScript)。

window.scrollTo(0, 2000);
document.querySelector('button').addEventListener('click', function(e){
  window.scrollTo(0, 0);
});
html, body {
  scroll-behavior: smooth;
}
<button style="margin: 2000px 0;">Scroll to top (JavaScript)</button> 
<a href="#">Link to smoothly scroll to top of page (no JavaScript)</a>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接