单击锚链接时平滑滚动

Onl*_*ere 451 javascript anchor jquery scroll hyperlink

我的页面上有几个超链接.用户在访问我的帮助部分时将阅读的常见问题解答.

使用Anchor链接,我可以使页面滚动到锚点并引导用户.

有没有办法让滚动顺畅?

但请注意他正在使用自定义JavaScript库.也许jQuery提供像这样的东西?

Jos*_*ber 1083

2018年4月更新:现在有一种本地方式可以做到这一点:

document.querySelectorAll('a[href^="#"]').forEach(anchor => {
    anchor.addEventListener('click', function (e) {
        e.preventDefault();

        document.querySelector(this.getAttribute('href')).scrollIntoView({
            behavior: 'smooth'
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

目前仅在最前沿的浏览器中支持此功能.


对于较旧的浏览器支持,您可以使用此jQuery技术:

$(document).on('click', 'a[href^="#"]', function (event) {
    event.preventDefault();

    $('html, body').animate({
        scrollTop: $($.attr(this, 'href')).offset().top
    }, 500);
});
Run Code Online (Sandbox Code Playgroud)

这里是小提琴:http://jsfiddle.net/9SDLw/


如果您的目标元素没有ID,并且您通过它链接到它name,请使用以下命令:

$('a[href^="#"]').click(function () {
    $('html, body').animate({
        scrollTop: $('[name="' + $.attr(this, 'href').substr(1) + '"]').offset().top
    }, 500);

    return false;
});
Run Code Online (Sandbox Code Playgroud)

为了提高性能,您应该缓存该$('html, body')选择器,以便每次单击锚点都不会运行它:

var $root = $('html, body');

$('a[href^="#"]').click(function () {
    $root.animate({
        scrollTop: $( $.attr(this, 'href') ).offset().top
    }, 500);

    return false;
});
Run Code Online (Sandbox Code Playgroud)

如果要更新URL,请在animate回调中执行此操作:

var $root = $('html, body');

$('a[href^="#"]').click(function() {
    var href = $.attr(this, 'href');

    $root.animate({
        scrollTop: $(href).offset().top
    }, 500, function () {
        window.location.hash = href;
    });

    return false;
});
Run Code Online (Sandbox Code Playgroud)

  • 这似乎从URL中删除了#extension,破坏了后退功能.有没有解决的办法? (10认同)
  • @CreateSean - `scrollTop:$(href).offset().top - 72` (4认同)
  • 我认为在这里缓存`html,body`对象是不必要的,每次点击运行一次选择器并不是那么多. (4认同)
  • @JosephSilber不应该是`scrollTop:$(this.hash).offset().top`而不是`scrollTop:$(this.href).offset().top`? (2认同)
  • 第一个解决方案是最好的和最现代的,您可以使用此polyfill来支持旧浏览器上的此行为[polyfill](https://github.com/iamdustan/smoothscroll) (2认同)
  • 这个解决方案有效。不幸的是,截至 2020 年 8 月,我必须使用 jQuery 版本才能平滑滚动,才能在 Safari 中正常工作。 (2认同)

And*_*par 161

正确的语法是:

//Smooth scrolling with links
$('a[href*=\\#]').on('click', function(event){     
    event.preventDefault();
    $('html,body').animate({scrollTop:$(this.hash).offset().top}, 500);
});

// Smooth scrolling when the document is loaded and ready
$(document).ready(function(){
  $('html,body').animate({scrollTop:$(location.hash).offset().??top}, 500);
});
Run Code Online (Sandbox Code Playgroud)

简化:干

function smoothScrollingTo(target){
  $('html,body').animate({scrollTop:$(target).offset().?top}, 500);
}
$('a[href*=\\#]').on('click', function(event){     
    event.preventDefault();
    smoothScrollingTo(this.hash);
});
$(document).ready(function(){
  smoothScrollingTo(location.hash);
});
Run Code Online (Sandbox Code Playgroud)

说明href*=\\#:

  • *意味着它匹配包含#char的内容.因此只匹配锚点.有关此含义的更多信息,请参见此处
  • \\是因为它#是css选择器中的一个特殊字符,所以我们必须将其转义.

  • 我不得不将`$('a')`更改为`$('a [href*=#]')`以仅提供锚定网址 (8认同)
  • 另外,'#'是一个特殊字符,它需要像这样转义:`a [href ^ = \\#]` (3认同)
  • 这导致链接到其他页面上的锚点停止工作.通过添加条件if($($(this.hash).selector).length){...平滑滚动来解决.} (3认同)
  • @okliv这将服务太多,例如javascript链接,如`<a href="javascript:$('#test').css('background-color','#000')">测试</a> `.你应该使用`$('[href ^ =#]')`来匹配所有以哈希字符开头的url. (2认同)
  • 首次访问新页面时如何设置动画?例如通过点击:website.com/newpage/#section2。我希望它加载页面然后向下滚动。那可能吗? (2认同)
  • 使用 `href*=\\#` 而不是 `href^=\\#` 时要小心,您可能还需要检查路径名以确保它是同一页面的链接。我们遇到了实际上链接到另一个页面的哈希链接的问题 (2认同)

Cri*_*yes 54

CSS3的新热点.这比本页面上列出的每种方法都容易得多,不需要Javascript.只需在css中输入以下代码,突然链接指向您自己页面内的位置就会有一个平滑的滚动动画.

html{scroll-behavior:smooth}
Run Code Online (Sandbox Code Playgroud)

之后,任何指向div的链接都会顺利地滑向这些部分.

<a href="#section">Section1</a>
Run Code Online (Sandbox Code Playgroud)

顺便说一下,我花了好几个小时试图让它发挥作用.在一些不起眼的评论部分找到了解决方案.它有缺陷,不适用于某些标签.没有在体内工作.当我把它放在CSS文件中的html {}时,它终于奏效了.

  • 这将是未来几年最相关的答案。 (4认同)
  • 我可以很方便,但是它们[有缺点](https://css-tricks.com/downsides-of-smooth-scrolling/) (3认同)
  • 不错,但是要小心,因为目前Safari和显然不是Explorer支持的(03/2019) (3认同)
  • 不错的解决方案,只有 74.8% 的覆盖率是有限的。也许在将来 (3认同)
  • 太棒了。多谢。 (2认同)

小智 26

不需要任何js只需使用scroll-behavior: smooth at html标签就是这样

html{
scroll-behavior: smooth;
}
Run Code Online (Sandbox Code Playgroud)


Phi*_*der 21

$('a[href*=#]').click(function(event){
    $('html, body').animate({
        scrollTop: $( $.attr(this, 'href') ).offset().top
    }, 500);
    event.preventDefault();
});
Run Code Online (Sandbox Code Playgroud)

这对我来说很完美

  • “event.preventDefault();” 可以代替“return false;” (2认同)
  • 很遗憾地说,但无法快速工作并显示在名为锚点的页面上,没有任何平滑度。 (2认同)

coc*_*ffs 16

我很惊讶没有人发布了一个原生解决方案,它还负责更新浏览器位置哈希以匹配.这里是:

let anchorlinks = document.querySelectorAll('a[href^="#"]')
 
for (let item of anchorlinks) { // relitere 
    item.addEventListener('click', (e)=> {
        let hashval = item.getAttribute('href')
        let target = document.querySelector(hashval)
        target.scrollIntoView({
            behavior: 'smooth',
            block: 'start'
        })
        history.pushState(null, null, hashval)
        e.preventDefault()
    })
}
Run Code Online (Sandbox Code Playgroud)

请参阅教程:http://www.javascriptkit.com/javatutors/scrolling-html-bookmark-javascript.shtml

  • 我最喜欢这个答案。但是 afais 无法提供偏移量。在固定标头的情况下需要。 (2认同)

小智 11

我建议你制作这个通用代码:

$('a[href^="#"]').click(function(){

var the_id = $(this).attr("href");

    $('html, body').animate({
        scrollTop:$(the_id).offset().top
    }, 'slow');

return false;});
Run Code Online (Sandbox Code Playgroud)

你可以在这里看到一篇非常好的文章:jquery-effet-smooth-scroll-defilement-fluide

  • 这不是通用的,这是jQuery. (8认同)

Was*_*siF 7

只有CSS

html {
    scroll-behavior: smooth !important;
}
Run Code Online (Sandbox Code Playgroud)

您只需要添加此内容。现在,您的内部链接滚动行为将像流一样平滑。

要了解详细信息,请阅读本文

  • 好的!为什么这不是公认的答案?我们不需要那些 JavaScript! (2认同)
  • 它效果很好,这应该是公认的答案。 (2认同)
  • 这是有史以来平滑滚动的最佳解决方案!谢谢! (2认同)
  • 这是最好的答案。非常感谢瓦西夫 (2认同)

Kin*_*der 6

$(function() {
  $('a[href*=#]:not([href=#])').click(function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      if (target.length) {
        $('html,body').animate({
          scrollTop: target.offset().top
        }, 1000);
        return false;
      }
    }
  });
});
Run Code Online (Sandbox Code Playgroud)

官方:http: //css-tricks.com/snippets/jquery/smooth-scrolling/


hev*_*ev1 6

有关平滑滚动方法的更全面列表,请参阅我的回答此处


您可以使用window.scroll()withbehavior: smooth并将top其设置为锚标记的偏移顶部,以确保锚标记位于视口的顶部。

document.querySelectorAll('a[href^="#"]').forEach(a => {
    a.addEventListener('click', function (e) {
        e.preventDefault();
        var href = this.getAttribute("href");
        var elem = document.querySelector(href)||document.querySelector("a[name="+href.substring(1, href.length)+"]");
        //gets Element with an id of the link's href 
        //or an anchor tag with a name attribute of the href of the link without the #
        window.scroll({
            top: elem.offsetTop, 
            left: 0, 
            behavior: 'smooth' 
        });
        //if you want to add the hash to window.location.hash
        //you will need to use setTimeout to prevent losing the smooth scrolling behavior
       //the following code will work for that purpose
       /*setTimeout(function(){
            window.location.hash = this.hash;
        }, 2000); */
    });
});
Run Code Online (Sandbox Code Playgroud)

演示:

document.querySelectorAll('a[href^="#"]').forEach(a => {
    a.addEventListener('click', function (e) {
        e.preventDefault();
        var href = this.getAttribute("href");
        var elem = document.querySelector(href)||document.querySelector("a[name="+href.substring(1, href.length)+"]");
        //gets Element with an id of the link's href 
        //or an anchor tag with a name attribute of the href of the link without the #
        window.scroll({
            top: elem.offsetTop, 
            left: 0, 
            behavior: 'smooth' 
        });
        //if you want to add the hash to window.location.hash
        //you will need to use setTimeout to prevent losing the smooth scrolling behavior
       //the following code will work for that purpose
       /*setTimeout(function(){
            window.location.hash = this.hash;
        }, 2000); */
    });
});
Run Code Online (Sandbox Code Playgroud)
a, a:visited{
  color: blue;
}

section{
  margin: 500px 0px; 
  text-align: center;
}
Run Code Online (Sandbox Code Playgroud)

您只需将 CSS 属性设置scroll-behaviorsmooth(大多数现代浏览器都支持)即可消除对 Javascript 的需要。

<a href="#section1">Section 1</a>
<br/>
<a href="#section2">Section 2</a>
<br/>
<a href="#section3">Section 3</a>
<br/>
<a href="#section4">Section 4</a>
<section id="section1">
<b style="font-size: 2em;">Section 1</b>
<p>Lorem ipsum dolor sit amet, et vis laudem utroque, iusto forensibus neglegentur eu duo. Eu pro fuisset salutandi philosophia, discere persecuti qui te. Eos ad quodsi dissentias, ei odio viris signiferumque mei. Putent iuvaret perpetua nec eu. Has no ornatus vivendum. Adhuc nonumes ex vim, in suas rebum graecis mei, usu ad causae recusabo. Idque vituperata vel ea.

Veri verterem pro ex. Ad error omnes est, id sit lorem legendos. Eos vidit ullum ne, tale tantas omittam est ut. Nobis maiorum efficiendi eu mei. Eos et debet placerat signiferumque. Per eu propriae electram.

Impetus percipit menandri te ius, mea ne stet posse fabellas. Aliquid corrumpit vel no, mei in diam praesent contentiones. Qui veniam suscipit probatus ex. No autem homero perfecto quo, eos choro facilis ut. Te quo cibo interesset. Vel verear praesent in, menandri deserunt ad his.

Labore admodum consetetur has et. Possit facilisi eu sed, lorem iriure eum id, pri ei consul necessitatibus. Est te iusto epicuri. Vis no graece putent mentitum, rebum facete offendit nec in. In duis vivendo sed, vel id enim voluptatibus. Velit sanctus ne mel, quem sumo suavitate mel cu, mea ea nullam feugiat.

Tincidunt suscipiantur no pro. Vel ut novum mucius molestie, ut tale ipsum intellegebat mei, mazim accumsan voluptaria ea nam. Posidonium theophrastus ut sea, stet viris hendrerit pro ex, sonet mentitum ne quo. Vim duis feugiat ex, nec eu probo doming persecuti. Velit zril nam in, est commodo splendide id. Et aperiri fuisset iracundia usu. Eu nec iusto audire repudiare.<p/>
<section>
<section id="section2">
<b style="font-size: 2em;">Section 2</b>
<p>Lorem ipsum dolor sit amet, et vis laudem utroque, iusto forensibus neglegentur eu duo. Eu pro fuisset salutandi philosophia, discere persecuti qui te. Eos ad quodsi dissentias, ei odio viris signiferumque mei. Putent iuvaret perpetua nec eu. Has no ornatus vivendum. Adhuc nonumes ex vim, in suas rebum graecis mei, usu ad causae recusabo. Idque vituperata vel ea.

Veri verterem pro ex. Ad error omnes est, id sit lorem legendos. Eos vidit ullum ne, tale tantas omittam est ut. Nobis maiorum efficiendi eu mei. Eos et debet placerat signiferumque. Per eu propriae electram.

Impetus percipit menandri te ius, mea ne stet posse fabellas. Aliquid corrumpit vel no, mei in diam praesent contentiones. Qui veniam suscipit probatus ex. No autem homero perfecto quo, eos choro facilis ut. Te quo cibo interesset. Vel verear praesent in, menandri deserunt ad his.

Labore admodum consetetur has et. Possit facilisi eu sed, lorem iriure eum id, pri ei consul necessitatibus. Est te iusto epicuri. Vis no graece putent mentitum, rebum facete offendit nec in. In duis vivendo sed, vel id enim voluptatibus. Velit sanctus ne mel, quem sumo suavitate mel cu, mea ea nullam feugiat.

Tincidunt suscipiantur no pro. Vel ut novum mucius molestie, ut tale ipsum intellegebat mei, mazim accumsan voluptaria ea nam. Posidonium theophrastus ut sea, stet viris hendrerit pro ex, sonet mentitum ne quo. Vim duis feugiat ex, nec eu probo doming persecuti. Velit zril nam in, est commodo splendide id. Et aperiri fuisset iracundia usu. Eu nec iusto audire repudiare.</p>
<section>
<section id="section3">
<b style="font-size: 2em;">Section 3</b>
<p>
Lorem ipsum dolor sit amet, et vis laudem utroque, iusto forensibus neglegentur eu duo. Eu pro fuisset salutandi philosophia, discere persecuti qui te. Eos ad quodsi dissentias, ei odio viris signiferumque mei. Putent iuvaret perpetua nec eu. Has no ornatus vivendum. Adhuc nonumes ex vim, in suas rebum graecis mei, usu ad causae recusabo. Idque vituperata vel ea.

Veri verterem pro ex. Ad error omnes est, id sit lorem legendos. Eos vidit ullum ne, tale tantas omittam est ut. Nobis maiorum efficiendi eu mei. Eos et debet placerat signiferumque. Per eu propriae electram.

Impetus percipit menandri te ius, mea ne stet posse fabellas. Aliquid corrumpit vel no, mei in diam praesent contentiones. Qui veniam suscipit probatus ex. No autem homero perfecto quo, eos choro facilis ut. Te quo cibo interesset. Vel verear praesent in, menandri deserunt ad his.

Labore admodum consetetur has et. Possit facilisi eu sed, lorem iriure eum id, pri ei consul necessitatibus. Est te iusto epicuri. Vis no graece putent mentitum, rebum facete offendit nec in. In duis vivendo sed, vel id enim voluptatibus. Velit sanctus ne mel, quem sumo suavitate mel cu, mea ea nullam feugiat.

Tincidunt suscipiantur no pro. Vel ut novum mucius molestie, ut tale ipsum intellegebat mei, mazim accumsan voluptaria ea nam. Posidonium theophrastus ut sea, stet viris hendrerit pro ex, sonet mentitum ne quo. Vim duis feugiat ex, nec eu probo doming persecuti. Velit zril nam in, est commodo splendide id. Et aperiri fuisset iracundia usu. Eu nec iusto audire repudiare.</p>
<section>
<a style="margin: 500px 0px; color: initial;" name="section4">
<b style="font-size: 2em;">Section 4 <i>(this is an anchor tag, not a section)</i></b>
</a>
<p>
Lorem ipsum dolor sit amet, et vis laudem utroque, iusto forensibus neglegentur eu duo. Eu pro fuisset salutandi philosophia, discere persecuti qui te. Eos ad quodsi dissentias, ei odio viris signiferumque mei. Putent iuvaret perpetua nec eu. Has no ornatus vivendum. Adhuc nonumes ex vim, in suas rebum graecis mei, usu ad causae recusabo. Idque vituperata vel ea.

Veri verterem pro ex. Ad error omnes est, id sit lorem legendos. Eos vidit ullum ne, tale tantas omittam est ut. Nobis maiorum efficiendi eu mei. Eos et debet placerat signiferumque. Per eu propriae electram.

Impetus percipit menandri te ius, mea ne stet posse fabellas. Aliquid corrumpit vel no, mei in diam praesent contentiones. Qui veniam suscipit probatus ex. No autem homero perfecto quo, eos choro facilis ut. Te quo cibo interesset. Vel verear praesent in, menandri deserunt ad his.

Labore admodum consetetur has et. Possit facilisi eu sed, lorem iriure eum id, pri ei consul necessitatibus. Est te iusto epicuri. Vis no graece putent mentitum, rebum facete offendit nec in. In duis vivendo sed, vel id enim voluptatibus. Velit sanctus ne mel, quem sumo suavitate mel cu, mea ea nullam feugiat.

Tincidunt suscipiantur no pro. Vel ut novum mucius molestie, ut tale ipsum intellegebat mei, mazim accumsan voluptaria ea nam. Posidonium theophrastus ut sea, stet viris hendrerit pro ex, sonet mentitum ne quo. Vim duis feugiat ex, nec eu probo doming persecuti. Velit zril nam in, est commodo splendide id. Et aperiri fuisset iracundia usu. Eu nec iusto audire repudiare.</p>
<script>
document.querySelectorAll('a[href^="#"]').forEach(a => {
        a.addEventListener('click', function (e) {
            e.preventDefault();
            var href = this.getAttribute("href");
            var elem = document.querySelector(href)||document.querySelector("a[name="+href.substring(1, href.length)+"]");
            window.scroll({
                top: elem.offsetTop, 
                left: 0, 
                behavior: 'smooth' 
            });
        });
    });
</script>
Run Code Online (Sandbox Code Playgroud)
html, body{
  scroll-behavior: smooth;
}
a, a:visited{
  color: blue;
}

section{
  margin: 500px 0px; 
  text-align: center;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

使用 JQuery:

$('a[href*=#]').click(function(){
  $('html, body').animate({
    scrollTop: $( $.attr(this, 'href') ).offset().top
  }, 500);
  return false;
});
Run Code Online (Sandbox Code Playgroud)


San*_*osh 5

There is a css way of doing this using scroll-behavior. Add the following property.

    scroll-behavior: smooth;
Run Code Online (Sandbox Code Playgroud)

And that is it. No JS required.

    scroll-behavior: smooth;
Run Code Online (Sandbox Code Playgroud)
a {
  display: inline-block;
  width: 50px;
  text-decoration: none;
}
nav, scroll-container {
  display: block;
  margin: 0 auto;
  text-align: center;
}
nav {
  width: 339px;
  padding: 5px;
  border: 1px solid black;
}
scroll-container {
  display: block;
  width: 350px;
  height: 200px;
  overflow-y: scroll;
  scroll-behavior: smooth;
}
scroll-page {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 5em;
}
Run Code Online (Sandbox Code Playgroud)

PS: please check the browser compatibility.


Bla*_*bam 5

这里已经有了很多好的答案-但是它们都缺少必须排除空锚的事实。否则,一旦单击空锚,这些脚本就会生成JavaScript错误。

我认为正确的答案是这样的:

$('a[href*=\\#]:not([href$=\\#])').click(function() {
    event.preventDefault();

    $('html, body').animate({
        scrollTop: $($.attr(this, 'href')).offset().top
    }, 500);
});
Run Code Online (Sandbox Code Playgroud)

  • 另外,当您从不同的网址单击哈希链接时,您需要考虑,因此会有很多“window.location....”和“$(this).attr('href')”。 substring(...)` 处理 (2认同)

Lal*_*uak 5

对哈希 id 滚动的平滑滚动有本机支持。

html {
  scroll-behavior: smooth;
}
Run Code Online (Sandbox Code Playgroud)

你可以看看:https : //www.w3schools.com/howto/howto_css_smooth_scroll.asp#section2