使用 IntersectionObserver 的 Sticky header 实现
Sticky header implementation with IntersectionObserver
我正在执行粘性 header 实现 - 我不想使用 position: sticky;
因为我没有看到好的 polyfill 所以我尝试使用 IntersectionObserver API 代替。问题是——我不太喜欢它提供的行为,因为它的条目可能会随机延迟发出。如果您逐渐滚动,此解决方案可以正常工作,但如果您滚动得更快,header 会上升,并且只有在延迟响应后,它才会获得 fixed
class 并以显着的跳跃定位,尤其是在大页面上。有什么方法可以实现更好的响应,或者 IntersectionObserver 不适合我的目的?
const header = document.querySelector('.header');
const headerPositionNotifier = document.createElement('div');
headerPositionNotifier.classList.add('header-position-notifier')
header.parentNode.insertBefore(headerPositionNotifier, header);
const options = {
threshold: [0]
};
const callback = (entries) => {
entries.forEach(({
intersectionRatio
}) => {
if (intersectionRatio == 0) {
header.classList.add('fixed')
} else {
header.classList.remove('fixed')
}
})
}
const io = new IntersectionObserver(callback, options);
io.observe(headerPositionNotifier);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
text-align: center;
font-family: Arial;
color: white;
letter-spacing: 10px;
}
.banner {
background: orange;
padding: 20px;
}
.parent {
background: mediumvioletred;
position: relative;
}
.header {
background: salmon;
padding: 40px 0;
}
.content {
background: #444;
padding: 40px 0;
height: 2000px;
}
.fixed {
position: fixed;
top: 0;
left: 0;
right: 0;
}
.header-position-notifier {
height: 1px;
}
<div class="banner">
BANNER
</div>
<div class="parent">
<div class="header">
HEADER
</div>
<div class="content"></div>
</div>
如果您不能为此使用 CSS,那您就不走运了。延迟仅来自您无法消除的滚动事件的延迟。正如您所说,在繁重的页面上,情况会变得更糟。即使在不同的浏览器上,情况也或多或少更糟。我更愿意将 css position sticky 和 intersection observer 结合起来。
我正在执行粘性 header 实现 - 我不想使用 position: sticky;
因为我没有看到好的 polyfill 所以我尝试使用 IntersectionObserver API 代替。问题是——我不太喜欢它提供的行为,因为它的条目可能会随机延迟发出。如果您逐渐滚动,此解决方案可以正常工作,但如果您滚动得更快,header 会上升,并且只有在延迟响应后,它才会获得 fixed
class 并以显着的跳跃定位,尤其是在大页面上。有什么方法可以实现更好的响应,或者 IntersectionObserver 不适合我的目的?
const header = document.querySelector('.header');
const headerPositionNotifier = document.createElement('div');
headerPositionNotifier.classList.add('header-position-notifier')
header.parentNode.insertBefore(headerPositionNotifier, header);
const options = {
threshold: [0]
};
const callback = (entries) => {
entries.forEach(({
intersectionRatio
}) => {
if (intersectionRatio == 0) {
header.classList.add('fixed')
} else {
header.classList.remove('fixed')
}
})
}
const io = new IntersectionObserver(callback, options);
io.observe(headerPositionNotifier);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
text-align: center;
font-family: Arial;
color: white;
letter-spacing: 10px;
}
.banner {
background: orange;
padding: 20px;
}
.parent {
background: mediumvioletred;
position: relative;
}
.header {
background: salmon;
padding: 40px 0;
}
.content {
background: #444;
padding: 40px 0;
height: 2000px;
}
.fixed {
position: fixed;
top: 0;
left: 0;
right: 0;
}
.header-position-notifier {
height: 1px;
}
<div class="banner">
BANNER
</div>
<div class="parent">
<div class="header">
HEADER
</div>
<div class="content"></div>
</div>
如果您不能为此使用 CSS,那您就不走运了。延迟仅来自您无法消除的滚动事件的延迟。正如您所说,在繁重的页面上,情况会变得更糟。即使在不同的浏览器上,情况也或多或少更糟。我更愿意将 css position sticky 和 intersection observer 结合起来。