聊聊页面中的锚点效果和回到顶部

聊聊页面中的锚点效果和回到顶部页面中的锚点各位想必都 了如指掌 其基于 a 链接 同页面跳转 和 id 属性标签的历史问题 可能有人不知道的是 HTML 中的 id 非常神奇 id 属性的元素不仅可以在 js 中直接使用 而不必先获取 还可以和 url 相关联 直接用 id 访问是旧版本 js 遗留下来的特性 浏览器会建立 window 实例的 id 同名属性 这是为了兼容旧的网页 但不要依赖这个特性 在含有特殊字符或者和 window 实例的其他属性有冲突时可能失效 我们都知道 锚点应该这样用 ahref 这里写 号 id 名 去这里 amp l ahref 这里写 号 id 名

页面中的锚点各位想必都“了如指掌”,其基于a链接“同页面跳转”和“id属性标签的历史问题”。

我们都知道,锚点应该这样用:

<a href="这里写#号+id名">去这里 
     a> <div id="上面a中引用的id名">我是目的地 
      div> 

如此便可。

但是这里面有两个小问题:

  1. 使用锚点后url中也会带有href中的字符串(#号+id名)
  2. 因为是类似跳转方式,所以过程非常生硬

以前来说用锚点肯定是不现实的,所以我们需要找到一个适合的API。

并且根据上一篇文章(点击阅读文章)中所提,document下的scrollTop API可为我们提供文档流(页面整体区域)向上滚动了多少距离。

笔者在这里再次提醒各位要区分js中inner系、page系、client系、offset系、outer系、screen系…事件,他们的含义各不相同。比如常说的offsetTop/Left,是距离上一级父元素的上/左边距,通常用 if(dom.parentElement) 做累加求的是“距离文档流顶部的距离”,就不适用于此处。

将二者结合起来使用,就可以达到:若想要展示的区域在下方,就让文档流不断向上滚动,直到此区域滑动到可视区顶端;反之若想要展示的区域已经滑过,就让文档流不断向下滚动。

/ leftBtn:侧边栏中所有负责页面滚动的div,都有一个class属性为left-btn i:left-btn所属div的下标(第几个) .mao1/2/3:页面中负责“滑到顶部”的div,一般是某一个区域的小标题 */ let leftBtn=document.querySelectorAll(".left-btn") function gotoTop(i,top){ 
    var timer=null; leftBtn[i].onclick=function(){ 
    let scrollTop=document.body.scrollTop ||document.documentElement.scrollTop || window.pageYOffset // 若目标位置在当前位置上方 if(scrollTop>top){ 
    clearInterval(timer) timer=null; timer=setInterval(function(){ 
    scrollTop=scrollTop-90<top?top:scrollTop-90; document.body.scrollTop=document.documentElement.scrollTop=window.pageYOffset=scrollTop if(scrollTop<=top){ 
    clearInterval(timer); timer=null; } },50) // 目标位置在当前位置下方 }else if(scrollTop<top){ 
    clearInterval(timer) timer=null; timer=setInterval(function(){ 
    scrollTop=scrollTop+90>top?top:scrollTop+90; document.body.scrollTop=document.documentElement.scrollTop=window.pageYOffset=scrollTop if(scrollTop>=top){ 
    clearInterval(timer); timer=null; } },50) } } } 

使用如:

let one_top=document.querySelector(".mao1").getBoundingClientRect().top let two_top=document.querySelector(".mao2").getBoundingClientRect().top let thr_top=document.querySelector(".mao3").getBoundingClientRect().top gotoTop(0,one_top); gotoTop(1,two_top); gotoTop(2,thr_top); 

这样就能达到上面展示的效果了。

这里面需要注意的是:setInterval() 定时器的清除!
如果上方代码去掉第14、15、26、27行,则页面滚动行为会发生错误。看上去似乎是clearInterval失效了!其实这个问题本身是由于js定时器特性产生的。clearInterval是根据定时器本身的标识来进行清除的,如果在期间生成了新的interval,并覆盖timer标识对象,旧有的timer定时器对象并不会被停止和清除,而且标识也会丢失导致再也无法被清除,所以写定时器时一定要注意。建议在调用某个定时器任务的函数的时候,一定一开始就把之前的定时器先清除!

这个问题到这里似乎很好的解决了。但是上面代码毕竟还是太长了,而且里面要进行严格的判断以决定开始和结束(定时器的增加和删除),似乎稍有不妥。

不过别急,js更新了另一个神器 —— scrollIntoView() ,原先这个API的作用就是让指定的div的顶部跳到窗口可视区顶部(从效果上看类似锚点),但是更新后增加了配置参数:

dom.scrollIntoView({ 
    behavior:"smooth" // ! }) 

这个参数的作用就是“平滑滚动”!不过由于新所以兼容性目前还不算很好,但是也无妨,毕竟它原本的作用还在,可以把新特性当做“只对少数用户更新的体验”。


说完了锚点效果,来说说页面中普遍存在的“回到顶部”。

同样的,之前笔者做社团官网的时候就采用了控制scrollTop不断--的方法。现在看来太麻烦了,用上面提到的 scrollIntoView() API就可完成:
目前大部分官网/网站都采用了在页面顶部(左上角)放一张logo的形式。针对使用这种形式的网站,若是logo所在div不是采用 position:fixed; 的方式固定在顶部的话,我们可以将img外面包裹一层a标签,然后就可以在“回到顶部”按钮的事件中这么写:

document.links[0].scrollIntoView({ 
     behavior:"smooth" }) //或者 直接定位图片 document.images[0].scrollIntoView({ 
    behavior:"smooth"}) 

scrollIntoView

这里还要提到js中后来新加入的两个原生API:scrollTo(滚动到哪里) 和 scrollBy(滚动多少距离)。这里为啥提到这俩?因为scrillTo这个API可以在ie上使用!它被支持在window上,比如:回到顶部window.scrollTo(0,0);
但这里也只是提一句让各位有个印象,非要用在本文所提场景下则大可不必。


说到这,前几天惊奇的发现CSS中多了一个控制页面滚动的属性!(去年年底开始支持的)原生平滑滚动定位 —— scroll-behavior ,它有两个值:

  1. auto:初始值。啥也没有。
  2. smooth:作用在滚动容器元素上,可以让容器内的滚动变得平滑。

比如在笔者文章中多次出现的tab框切换,如果你只设置了父容器的 overflow:hidden; 而子元素采用了相对父元素定位的方式展示(display、opacity、visibility都不行,因为他们本质上都不是通过位置移动展示元素的),那么就可以在父容器上加上一行:scroll-behavior: smooth;

效果贼好,生动了许多!

还有上面说的“回到顶部”(和“锚点”),如果不想用js实现而且又不抗拒url后面的小小“#”的话,其实你可以这么实现:

/ css样式 */ html, body { 
      scroll-behavior:smooth; } 
<a href="#">返回顶部 
       a> 

包括上面的“锚点效果”也可以这么来~

perfect!


元旦将至,提前祝各位元旦快乐,溜了溜了~

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/199793.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 下午12:12
下一篇 2026年3月20日 下午12:12


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号