我有一个页面,其中一个滚动条包含从数据库动态生成的带有div的表行。每个表行就像一个链接,有点像你在视频播放器旁边看到的YouTube播放列表。

当用户访问页面时,他们所在的选项应该会转到滚动div的顶部。这个功能正在工作。问题是,这有点太过分了。比如他们的选项高了10像素。因此,页面被访问,url被用来识别选择了哪个选项,然后将该选项滚动到滚动div的顶部。注意:这不是窗口的滚动条,这是一个带有滚动条的div。

我正在使用这段代码,使它移动选中的选项到div的顶部:

var pathArray = window.location.pathname.split( '/' );

var el = document.getElementById(pathArray[5]);

el.scrollIntoView(true);

它将它移动到div的顶部,但大约10个像素太高了。 有人知道怎么解决吗?


当前回答

解决方案,如果你是使用离子电容器,角材料,并需要支持iOS 11。

                document.activeElement.parentElement.parentElement.scrollIntoView({block: 'center', behavior: 'smooth'}); 

关键是滚动到父节点的父节点,也就是输入的包装器。这个包装器包含输入的标签,该标签现在不再被切断。

如果你只需要支持iOS 14,“block”中心参数实际上是有效的,所以这是足够的:

                document.activeElement.scrollIntoView({block: 'center', behavior: 'smooth'}); 

其他回答

基于之前的答案,我在一个Angular5项目中这样做。

开始:

// el.scrollIntoView(true);
el.scrollIntoView({
   behavior: 'smooth',
   block: 'start'
});
window.scrollBy(0, -10); 

但这样会产生一些问题,需要为scrollBy()设置timeout,如下所示:

//window.scrollBy(0,-10);
setTimeout(() => {
  window.scrollBy(0,-10)
  }, 500);

它在MSIE11和Chrome 68+中工作完美。我没有在FF测试过。500毫秒是我敢说的最短延迟。向下走有时会失败,因为平滑的滚动还没有完成。根据您自己的项目进行调整。

+1到Fred727为这个简单而有效的解决方案。

最简单的方法是,

html, body {
    scroll-behavior: smooth;
}

    html [id], body [id] {
        scroll-margin: 50px !important;
    }

使用您提供的代码

var pathArray = window.location.pathname.split( '/' );
var el = document.getElementById(pathArray[5]);
el.style.scrollMargin = '50px';
el.scrollIntoView(true);

根据arsenie - ii的回答:我有一个用例,其中滚动实体不是窗口本身,而是一个内部模板(在这种情况下是div)。在这个场景中,我们需要为滚动容器设置一个ID,并通过getElementById获取它来使用它的滚动函数:

<div class="scroll-container" id="app-content">
  ...
</div>
const yOffsetForScroll = -100
const y = document.getElementById(this.idToScroll).getBoundingClientRect().top;
const main = document.getElementById('app-content');
main.scrollTo({
    top: y + main.scrollTop + yOffsetForScroll,
    behavior: 'smooth'
  });

把它留在这里,以防有人面临类似的情况!

CSS滚动边距和滚动填充

你可能想看看新的CSS属性滚动填充和滚动边距。可以对滚动容器(在本例中为html)使用滚动填充,对容器内的元素使用滚动边距。

在你的例子中,你想为你想要滚动到视图中的元素添加scroll-margin-top,如下所示:

.example {
  scroll-margin-top: 10px;
}

这会影响scrollIntoView代码,如下所示:

const el = document.querySelector(".example");
el.scrollIntoView({block: "start", behavior: "smooth"});

这将导致视口滚动以使视口的上边界与元素的上边界对齐,但有10px的额外空间。换句话说,元素的这些属性被考虑在内:

padding-top border-top scroll-margin-top (而不是margin-top)

此外,如果html元素有滚动填充顶部设置,那么也会考虑这一点。

这适用于我的Chrome浏览器(平滑滚动,没有计时黑客)

它只是移动元素,开始滚动,然后再移动回来。

如果元素已经在屏幕上,则不会出现可见的“弹出”。

pos = targetEle.style.position;
top = targetEle.style.top;
targetEle.style.position = 'relative';
targetEle.style.top = '-20px';
targetEle.scrollIntoView({behavior: 'smooth', block: 'start'});
targetEle.style.top = top;
targetEle.style.position = pos;