使用IntersectionObserver的粘性标头实现

时间:2019-07-29 12:01:29

标签: javascript html css intersection-observer

我正在执行粘性标头实现-我不想使用position: sticky;,因为我没有看到好的填充,所以我尝试使用IntersectionObserver API。问题是-我真的不喜欢它提供的行为,因为它的条目可能会随机延迟地发出。如果逐步滚动,此解决方案效果很好,但如果滚动速度更快,则标题会上升,并且仅在延迟响应后才会获得fixed类,并且位置会明显跳升,尤其是在较重的页面上。有什么方法可以获得更好的响应,或者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>

1 个答案:

答案 0 :(得分:2)

如果您不能为此使用CSS,那么您不走运。延迟只是来自无法消除的滚动事件的延迟。如您所说,在沉重的页面上情况会更糟。即使在不同的浏览器上,情况也差不多。我更喜欢结合使用css位置粘性和作为交集观察器的后备。