我有一个粘性标题,它利用
IntersectionObserver
在卡住时获得一个类,然后隐藏一些元素并减小徽标的大小。当然,当标题的高度缩小时,滚动高度也会缩小,因此,如果您向下滚动“刚好足够”以缩小标题,它就会缩小,然后意识到它不再卡住,因此会增长,但这会导致它缩小再次增长,如此无限循环。这似乎在 Chrome 中最令人震惊,但我在 Firefox 中也看到过这种情况(尽管 Firefox 似乎能够识别发生了什么并自行解决)。
我尝试了很多事情,包括在类被删除时使用 setTimeout()
来延迟,在标题收缩时添加等效的
margin-bottom
,使用收缩空间的 height
显示隐藏元素,但似乎什么也没有解决这个问题。我知道我以前也在其他网站上看到过这种情况,我怀疑这只是缩小标题的系统性问题,但我能做些什么来防止这种情况发生吗?我没主意了。
const OBSERVER = new IntersectionObserver(
([e]) => e.target.classList.toggle("js-is-sticky", e.intersectionRatio < 1),
{
rootMargin: document.getElementById("wpadminbar") ? "-32px 0px 0px 0px" : "0px 0px 0px 0px",
threshold: [1],
}
);
OBSERVER.observe(document.querySelector(".sticky-block"));
CSS 和标记有点复杂(并且稍微不相关),因此如果需要,请参阅我们的演示网站。https://gepl.myweblinx.net/
编辑1:我看到
这个答案建议在保留正确高度的元素周围放置一个容器,但这不适用于position: sticky;
,因为
position: sticky;
仅适用于最近的容器(除非有人知道如何获取围绕这个?)编辑2:我对第一次编辑的答案想得太多了
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<style>
:root {
--lightGrey: #bbbbbb;
}
body {
margin: 0;
width: 100%;
height: 500%;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(9, auto);
grid-column-gap: 0px;
grid-row-gap: 0px;
}
header {
width: 100%;
grid-area: 1 / 1 / 1 / 4;
position: fixed;
top: 0;
z-index: 100;
background-color: var(--lightGrey);
}
.headerBackground {
grid-area: 1 / 1 / 1 / 4;
background-color: var(--lightGrey);
height: fit-content;
}
</style>
</head>
<body>
<header>My Header</header>
<div class="headerBackground">Background div</div>
</body>
<script>
// Changes the header once you have scrolled down by 100 pixels or more
$(window).scroll(function () {
if ($(window).scrollTop() >= 100) {
$('header').css('height', '20vw');
$('header').css({ 'font-size': '4vw', 'padding': '5vw' });
} else if ($(window).scrollTop() == 0) {
$('header').attr('style', '');
}
});
// This keeps the space behind the header at the same height as the header to get around the flickering sticky
$(".headerBackground").css({ 'height': ($("header").height() + 'px') });
</script>
</html>
threshold + buffer
时才允许标题增大,仅当滚动位置低于
threshold - buffer
时才缩小。要确定方向(标题是否应该增大或缩小),您可以跟踪标题的当前状态(缩小或展开)。使用 Svelte 的示例:
<script lang="ts">
let yScroll = $state(0);
let threshold = 50;
let buffer = 40;
let isShrunk = $state(false);
$effect(() => {
if (!isShrunk && yScroll >= threshold + buffer) {
isShrunk = true;
} else if (isShrunk && yScroll <= threshold - buffer) {
isShrunk = false;
}
});
</script>
<svelte:window bind:scrollY={yScroll} />
<header class="transition-all duration-500 {isShrunk ? 'h-16' : 'h-32'}">Header</header>