乐趣区

关于javascript:scrollIntoView方法导致整个页面产生偏移

问题形容

明天在做页面 UI 改版的时候发现,我之前应用的是dom.scrollIntoView(); 使得点击右侧题目编号的时候,让左侧题目滚动到页面可视区域。

如果不晓得 scrollIntoView 如果应用,我有篇文章专门写了 scrollIntoView 的简略应用:scrollIntoView() 让元素进入可视区域 · Issue #167

然而当初有个问题就是,当点击题目编号的时候,除了题目会滚动到可视区域,整个页面也会稍稍往上滚动,导致页面错位。

如下图所示,当我点击第 9 题的时候,左侧第 9 题挪动到视口中,然而整个页面包含导航栏都往上挪动了,且无奈在移回来,整个页面是没有滚动条的。

问题剖析

这个时候惟一的可能就是 scrollIntoView() 函数引起的问题。

我之前狐疑是不是该函数给整个页面加了transform 属性导致整个页面往上偏移,通过查看 css,发现没有。

没有想到方法。只能借助搜索引擎了,于是我在 Stack Overflow 下面找到了一篇文章:

javascript – ScrollIntoView() causing the whole page to move

说的正好是这种状况。

最高赞给出的解决办法是:放弃应用scrollIntoView 改用scrollTop 来操作滚动条。

var target = document.getElementById("target");
target.parentNode.scrollTop = target.offsetTop;

offsetTop:元素上外边框间隔父元素上内边框的间隔(简略来说就是元素绝对父元素上边的间隔)

这段代码好了解,就是以后须要显示的元素间隔父元素顶部的间隔,也就是滚动条滚动的高度。

这段代码执行后,就能够让该元素达到父元素顶部的地位。

注意事项:offsetTop 不肯定是绝对于父元素的,如果有很多父元素的话,它是绝对于第一个 定位的父元素 的。

如果第一个父元素未定位(绝对 relative、相对absolute 或固定fixed),则可能须要将第二行更改为:

target.parentNode.scrollTop = target.offsetTop- target.parentNode.offsetTop;

参考 offset 相干属性:Web/06- 一文搞懂 DOM 相干间隔问题

解决办法

代码如下,加上动画:

var target = document.getElementById("target");

$(target).animate({"scrollTop": target.offsetTop}, 'normal');

这是应用 jQuery 的animate 动画函数。

animate 函数应用办法:https://jquery.cuishifeng.cn/…

如果不应用 jQuery 的话,因为scrollTop 是 js 属性,不是 css 属性,所以不能应用transition 来设置动画。动画成果要本人写喽。

上面是一个参考例子:javascript – scrollTop animation without jquery

相干问题

相似的问题和解决办法如下链接:

  • scrollintoview-moves-the-whole-page-layout-up
  • scrollintoview-whole-page-shifting-down

(完)

原文首发地址:https://github.com/Daotin/fe-…

你也能够从上面中央找到我:

  • Github 个人主页
  • 公众号:前端队长
退出移动版