如何滚动HTML页面到给定的锚点?


264

我想让浏览器仅使用JavaScript即可将页面滚动到给定的锚点。

我在HTML代码中指定了nameid属性:

 <a name="anchorName">..</a>

要么

 <h1 id="anchorName2">..</h1>

通过导航到,我希望获得与您相同的效果http://server.com/path#anchorName。应滚动页面,使锚点位于页面可见部分的顶部附近。

Answers:


349
function scrollTo(hash) {
    location.hash = "#" + hash;
}

完全不需要jQuery!


91
那实际上并没有滚动,只是跳跃了。到那时,您最好只链接到锚点<a href="#anchorName">link</a>
Ryan

52
请注意,这只会工作一次。设置完哈希后,该页面将不会滚动到同一哈希,除非您将其更改为虚拟哈希然后再次进行设置。
Cristian Vrabie 2014年

13
您不应使用scrollTo,因为全局窗口对象已使用它。同样,该参数不应命名为hash,因为location.hash也已定义。您可以使用此代码:function scrollToHash(hashName) { location.hash = "#" + hashName; }
Markus Zeller

3
@MarkusZeller,为什么不应该将参数称为哈希?它不会与位置冲突,对吗?
Gherman

3
如果设置为“ scroll-behavior:smooth;”,则不会滚动。在html元素上
堆垛机

225

方法更简单:

var element_to_scroll_to = document.getElementById('anchorName2');
// Or:
var element_to_scroll_to = document.querySelectorAll('.my-element-class')[0];
// Or:
var element_to_scroll_to = $('.my-element-class')[0];
// Basically `element_to_scroll_to` just have to be a reference
// to any DOM element present on the page
// Then:
element_to_scroll_to.scrollIntoView();

22
起初,我以为Mandx正在拖钓,然后我尝试了一下,并且效果很好。除了我,我以前从未遇到过这种方法。 Mozilla Docs用于此方法。同样,这似乎在浏览器中也将得到很好的支持。
Jonathan Dumaine

2
我有很多问题,jQuery解决方案无法滚动。这为我节省了很多挫败感。
NuclearPeon 2014年

1
警告!如果该div上方的div包含浮动元素并且无法轻松确定其大小,则此方法可能会出现问题。
vogomatix

5
这是一个干净的解决方案,但是到目前为止,它不允许进行任何调整,而是进行硬滚动。有一个实验性参数scrollIntoViewOptions可以behavior: "smooth"选择,但目前仅与Firefox兼容。
rocha

如何制作动画?
SkuraZZ

124

您可以使用jQuerys .animate() .offset()scrollTop。喜欢

$(document.body).animate({
    'scrollTop':   $('#anchorName2').offset().top
}, 2000);

范例连结:http : //jsbin.com/unasi3/edit

如果你不想有生命使用.scrollTop()一样

$(document.body).scrollTop($('#anchorName2').offset().top);

location.hash

location.hash = '#' + anchorid;

1
至于创建选择器以查找<h1 id="anchorName"><a name="anchorName">,请使用$('#'+hash+',a[name='+hash+']')或稍作优化的选择器,该选择器$(document.getElementById(hash) || 'a[name='+hash+']')将首先通过id搜索元素,并仅在未找到a时才搜索a。
gnarf

@gnarf-不需要优化jQuery中的'#'选择器-它们已经为您优化。很容易看出您是否已阅读jQuery源代码。
CodeJoust

3
@CodeJoust-我在jQuery团队中,我已经阅读了很多次,是的,虽然已经过$("#selector")优化,但$("#selector,a[name='selector']")不会很快进行相同的优化。我想我2.5岁的评论听起来有些奇怪。“优化”是在a[name='selector']找到ID的情况下避免搜索,而不是对ID的搜索进行优化。
gnarf

1
我对这种方法很幸运:<a data-hash="about">关于</a> <script> $(“ [data-hash]”)。click(function(){var data = $(this) .attr(“ data-hash”); $(document.body).animate({'scrollTop':$(“#” + data).offset()。top},500);}); </ script>
Jazzy

32

jAndy的出色解决方案,但平滑滚动似乎在Firefox中无法正常工作。

以这种方式编写它也可以在Firefox中使用。

(function($) {
    $(document).ready(function() {
         $('html, body').animate({
           'scrollTop':   $('#anchorName2').offset().top
         }, 2000);
    });
})(jQuery);

在最新的Chrome版本中,这是我发现始终有效的唯一方法。谢谢你的提示!
gaborous

32

2018-2020年纯js:

有一个非常方便的滚动到元素的方法:

el.scrollIntoView({
  behavior: 'smooth', // smooth scroll
  block: 'start' // the upper border of the element will be aligned at the top of the visible part of the window of the scrollable area.
})

但据我了解,他没有以下选项的良好支持。

在此处输入图片说明

详细了解该方法。


如果有必要元素位于顶部:

const element = document.querySelector('#element')
const topPos = element.getBoundingClientRect().top + window.pageYOffset

window.scrollTo({
  top: topPos, // scroll so that the element is at the top of the view
  behavior: 'smooth' // smooth scroll
})

Codepen上的演示示例


如果您希望元素位于中心:

const element = document.querySelector('#element')
const rect = element.getBoundingClientRect() // get rects(width, height, top, etc)
const viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);

window.scroll({
  top: rect.top + rect.height / 2 - viewHeight / 2,
  behavior: 'smooth' // smooth scroll
});

Codepen上的演示示例


支持:

введитесюдаописаниеизображения

他们编写scroll的方法与相同scrollTo,但是在中支持更好scrollTo

有关该方法的更多信息


该解决方案效果非常好!感谢分享!
gaborous

29

没有JQuery的纯JavaScript解决方案。已在Chrome&Ie上测试,未在IOS上测试

function ScrollTo(name) {
  ScrollToResolver(document.getElementById(name));
}

function ScrollToResolver(elem) {
  var jump = parseInt(elem.getBoundingClientRect().top * .2);
  document.body.scrollTop += jump;
  document.documentElement.scrollTop += jump;
  if (!elem.lastjump || elem.lastjump > Math.abs(jump)) {
    elem.lastjump = Math.abs(jump);
    setTimeout(function() { ScrollToResolver(elem);}, "100");
  } else {
    elem.lastjump = null;
  }
}

演示:https : //jsfiddle.net/jd7q25hg/12/


1
抱歉对旧主题发表评论,但这对我来说效果最好,因为我的项目未使用JQuery。我注意到的唯一问题是,如果滚动到最顶部,它将丢失5个像素左右。
AntBirch '16

看到纯js版本非常令人耳目一新。我教学生们要始终保持内幕,并了解JQuery为他们做什么,因此这是一个很好的例子。
戴夫·埃弗里特

2
这应该是公认的答案:这是一个纯粹的js示例,并且可以实现所需的滚动动画效果。我将超时值调整为20,它可以正常工作。
Mark Ba​​rrasso

谢谢,我爱纯JavaScript解决方案
R01010010 '18

2
在IOS中的作品刚刚进行了测试。
Debbie Kurth

23

在2018年,您不需要jQuery这样简单的东西。内置scrollIntoView()方法支持“ behavior”属性,以平滑滚动到页面上的任何元素。您甚至可以使用哈希更新浏览器URL,以使其可添加书签。

滚动HTML书签的本教程开始,这是一种自动将平滑滚动添加到页面上所有锚点链接的本地方法:

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()
    })
}

2
消除对jQuery依赖的出色答案
Zai chang


14

平滑滚动到正确位置(2019)

获取正确的 y坐标并使用window.scrollTo({top: y, behavior: 'smooth'})

const id = 'anchorName2';
const yourElement = document.getElementById(id);
const y = yourElement.getBoundingClientRect().top + window.pageYOffset;

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

有偏移

scrollIntoView也是一个不错的选择,但在某些情况下可能无法完美运行。例如,当您需要其他偏移量时。与scrollTo您只需要添加这样的偏移量:

const yOffset = -10; 

window.scrollTo({top: y + yOffset, behavior: 'smooth'});

我认为您应该在CSS样式文件中添加以下内容: css html { scroll-behavior: smooth; }
parismiguel

5
$(document).ready ->
  $("a[href^='#']").click ->
    $(document.body).animate
      scrollTop: $($(this).attr("href")).offset().top, 1000

5

CSS-Tricks的解决方案在jQuery 2.2.0中不再起作用。它将引发选择器错误:

JavaScript运行时错误:语法错误,无法识别的表达式:a [href * =#]:not([href =#])

我通过更改选择器对其进行了修复。完整的代码段是这样的:

$(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;
    }
  }
 });
});

4

大多数答案不必要地复杂。

如果只想跳到目标元素,则不需要JavaScript:

# the link:
<a href="#target">Click here to jump.</a>

# target element:
<div id="target">Any kind of element.</div>

如果要动画滚动到目标,请参阅@Shahil的答案。


有时候,您需要动态地进行操作;即,不通过用户的直接行动。我相信这就是OP想要的。
jpaugh

1
是的,很明显,OP已经意识到锚链接功能。
isherwood '16


3

这是一个工作脚本,它将页面滚动到锚点。要进行设置,只需为锚链接提供一个ID,该ID与要滚动到的锚的name属性匹配。

<script>
jQuery(document).ready(function ($){ 
 $('a').click(function (){ 
  var id = $(this).attr('id');
  console.log(id);
  if ( id == 'cet' || id == 'protein' ) {
   $('html, body').animate({ scrollTop: $('[name="' + id + '"]').offset().top}, 'slow'); 
  }
 }); 
});
</script>

2

我知道这是一个很老的问题,但是我在css-tricks中找到了一个简单的jQuery解决方案。那就是我现在正在使用的那个。

$(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;
      }
    }
  });
});

1
选择器在jquery 2.2.0中引发异常。0x800a139e-JavaScript运行时错误:语法错误,无法识别的表达式:a [href * =#]:not([href =#])
Bill Shihara


2

vue2解决方案...添加简单数据属性以简单地强制更新

  const app = new Vue({ 
  ... 

  , updated: function() {
           this.$nextTick(function() {
           var uri = window.location.href
           var anchor = ( uri.indexOf('#') === -1 ) ? '' : uri.split('#')[1]
           if ( String(anchor).length > 0 && this.updater === 'page_load' ) {
              this.updater = "" // only on page-load !
              location.href = "#"+String(anchor)
           }
         })
        }
     });
     app.updater = "page_load"

 /* smooth scrolling in css - works in html5 only */
 html, body {
     scroll-behavior: smooth;
 }

0

使浏览器将页面滚动到给定锚点的最简单方法是键入您的style.css * {scroll-behavior:smooth;},然后在html导航中使用#NameOfTheSection

*{scroll-behavior: smooth;}
<a href="#scroll-to">Home<a/>

<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>

<section id="scroll-to">
<p>it will scroll down to this section</p>
</section>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.