我有一个用于我的网站的代码:
function clickMe() {
var element = document.getElementById('about');
element.scrollIntoView({
block: 'start',
behavior: 'smooth',
});
}
这个方法很好用,但我有一个固定的页眉,所以当代码滚动到该元素时,页眉会挡住它。
有没有一种方法可以设置偏移量并使其平稳滚动?
我有一个用于我的网站的代码:
function clickMe() {
var element = document.getElementById('about');
element.scrollIntoView({
block: 'start',
behavior: 'smooth',
});
}
这个方法很好用,但我有一个固定的页眉,所以当代码滚动到该元素时,页眉会挡住它。
有没有一种方法可以设置偏移量并使其平稳滚动?
有没有一种方法可以设置偏移,并使其平滑滚动?
#有,但不能使用scrollIntoView()
Element.scrollIntoView()的scrollIntoViewOptions不允许您使用偏移量。它仅在您想要滚动到元素的精确位置时有用。
但是,您可以使用Window.scrollTo()和选项来滚动到偏移位置,并且实现平滑过渡效果。
例如,如果您的标题高度为30px
,则可以执行以下操作:
function scrollToTargetAdjusted(){
var element = document.getElementById('targetElement');
var headerOffset = 45;
var elementPosition = element.getBoundingClientRect().top;
var offsetPosition = elementPosition + window.pageYOffset - headerOffset;
window.scrollTo({
top: offsetPosition,
behavior: "smooth"
});
}
这将平滑地滚动到您的元素,以便它不会被页眉遮挡而看不到。
注意:您要减去偏移量,因为您希望在滚动标题超过您的元素之前停止。
#在下面的片段中查看效果
您可以在下面的片段中比较两个选项。
<script type="text/javascript">
function scrollToTarget() {
var element = document.getElementById('targetElement');
element.scrollIntoView({
block: "start",
behavior: "smooth",
});
}
function scrollToTargetAdjusted() {
var element = document.getElementById('targetElement');
var headerOffset = 45;
var elementPosition = element.getBoundingClientRect().top;
var offsetPosition = elementPosition + window.pageYOffset - headerOffset;
window.scrollTo({
top: offsetPosition,
behavior: "smooth"
});
}
function backToTop() {
window.scrollTo(0, 0);
}
</script>
<div id="header" style="height:30px; width:100%; position:fixed; background-color:lightblue; text-align:center;"> <b>Fixed Header</b></div>
<div id="mainContent" style="padding:30px 0px;">
<button type="button" onclick="scrollToTarget();">element.scrollIntoView() smooth, header blocks view</button>
<button type="button" onclick="scrollToTargetAdjusted();">window.scrollTo() smooth, with offset</button>
<div style="height:1000px;"></div>
<div id="targetElement" style="background-color:red;">Target</div>
<br/>
<button type="button" onclick="backToTop();">Back to top</button>
<div style="height:1000px;"></div>
</div>
window.pageYOffset
已添加以解决与@coreyward评论相关的问题。
getBoundingClientRect().top
指的是元素与视口顶部之间的距离。当您想要使用 scrollBy
相对于当前位置滚动时这更有用,而在使用绝对值滚动的 scrollTo
中则不太有用。如果元素没有被相对定位的父元素包围,请考虑使用 offsetTop
。否则,您需要将 window.pageYOffset
添加到 getBoundingClientRect().top
上以获取适用于 scrollTo
的正确值。 - coreywardwindow.pageYOffset
hint. - Anurag Srivastavawindow
顶部时,我使用getBoundingClientRect()
遇到了问题。getBoundingClientRect()
更加具有一致性和多样性。 我使用了这里概述的方法来实现它,以使其按照预期工作。const element = document.getElementById('targetElement');
const offset = 45;
const bodyRect = document.body.getBoundingClientRect().top;
const elementRect = element.getBoundingClientRect().top;
const elementPosition = elementRect - bodyRect;
const offsetPosition = elementPosition - offset;
window.scrollTo({
top: offsetPosition,
behavior: 'smooth'
});
在实现时,请记得包含polyfill!
如果元素的高度很小(低于视窗),那么简单而优雅的解决方案如下:
element.scrollIntoView({ behavior: 'auto' /*or smooth*/, block: 'center' });
block: center
会滚动元素,使其中心位于视口的垂直中心位置,以便顶部标题不会覆盖它。
编辑8.5.22:过去使用了behavior: instant
,但已从浏览器中删除。
您可以像示例中那样使用scrollIntoView()
function clickMe() {
var element = document.getElementById('about');
element.scrollIntoView({
block: 'start',
behavior: 'smooth',
});
}
如果您将标题的高度与scroll-margin
属性添加到目标元素(about
)中:
.about {
scroll-margin: 100px;
}
没有其它必要的了。scroll-margin
在所有现代浏览器中均得到支持。
Søren D. Ptæus的回答几乎是正确的,但仅适用于用户在顶部时。这是因为getBoundingClientRect将始终获取相对高度,并且使用相对高度的window.scrollTo不起作用。
ekfuhrmann通过从body元素获取总高度并计算实际高度来改进了答案。但是,我认为它可以更容易,我们可以简单地使用相对位置并使用window.scrollBy。
注意:关键区别在于window.scrollBy。
const HEADER_HEIGHT = 45;
function scrollToTargetAdjusted(){
const element = document.getElementById('targetElement');
const elementPosition = element.getBoundingClientRect().top;
const offsetPosition = elementPosition - HEADER_HEIGHT;
window.scrollBy({
top: offsetPosition,
behavior: "smooth"
});
}
我尝试了其他解决方案,但是我得到了一些奇怪的行为。不过,这个对我有用。
function scrollTo(id) {
var element = document.getElementById(id);
var headerOffset = 60;
var elementPosition = element.offsetTop;
var offsetPosition = elementPosition - headerOffset;
document.documentElement.scrollTop = offsetPosition;
document.body.scrollTop = offsetPosition; // For Safari
}
并且风格:
html {
scroll-behavior: smooth;
}
padding
和负的margin
。由于我没有您的标记和代码,无法保证它适用于您,但是当我遇到类似问题时,我使用了这个解决方法。30px
,并且您想要一个偏移量为15px
,那么: #about {
padding-top: 45px; // this will allow you to scroll 15px below your 30px header
margin-top: -45px; // and this will make sure that you don't change your layout because of it
}
scroll-margin-top: 45px;
。 - Alireza还有 scroll-margin 和 scroll-padding。
对于我来说,scroll-padding 在这种情况下是最有用的。
https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-padding-top
https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-margin-top
/* Keyword values */
scroll-padding-top: auto;
/* <length> values */
scroll-padding-top: 10px;
scroll-padding-top: 1em;
scroll-padding-top: 10%;
/* Global values */
scroll-padding-top: inherit;
scroll-padding-top: initial;
scroll-padding-top: unset;
此外,您可以通过将滚动行为设置为平滑来使用平滑滚动。
/* Keyword values */
scroll-behavior: auto;
scroll-behavior: smooth;
/* Global values */
scroll-behavior: inherit;
scroll-behavior: initial;
scroll-behavior: revert;
scroll-behavior: unset;
不过,很可能不兼容Internet Explorer。
* {
scroll-behavior: smooth;
scroll-padding-top: 100px; /* this pixel should match fixed header height */
}
什么是平滑滚动?只需在CSS中添加scroll-behavior: smooth;
即可。
如果你想要的是在打开一个新页面后平滑滚动,那么这就是另一种方法。你可以在这里查看我的回答:here
如果你想要检查元素是否在视口内,那就是另外一回事了。我不确定你想找哪个。如果是这个问题,请确认一下,我会花更多时间为你总结答案。我也曾遇到过这个问题,最终解决了。
elementRef.current!.scrollIntoView({
behavior: 'smooth',
block: 'center'
})