当视口中有其他粘性元素时检测元素是否粘性

问题描述 投票:0回答:1

我需要检测粘性元素何时被固定/粘住。

如果当时只有一个粘性元素,那么使用这种方法可以正常工作。 请注意,技巧是设置

top: -1px 并检查元素是否离开视口

const stickyElements = document.querySelectorAll('.sticky-element'); const observer = new IntersectionObserver( ([entry]) => { entry.target.classList.toggle('pinned', entry.intersectionRatio < 1); }, { threshold: [1, 0.01] }, ); stickyElements.forEach((sticky, i) => { if (sticky) { observer.observe(sticky); } });
.sticky-element { position: sticky; top: -1px; z-index: 2; } .sticky-element.pinned { background: white; border-bottom: 1px solid #ccc; } .sticky-element.pinned { &:after { content: ' (pinned)'; } } .just-content { height: 100vh; display: flex; justify-content: center; align-items: center; background: #f8f8f8; }
<div class="sticky-element">I'm sticky</div>
<div class="just-content">I'm just normal element</div>
<div class="sticky-element">I'm sticky 1</div>
<div class="just-content">I'm just normal element</div>
<div class="sticky-element">I'm sticky 2</div>
<div class="just-content">I'm just normal element</div>

问题是当你尝试将它与上面的粘性元素结合时,让我们尝试一下:

const stickyElements = document.querySelectorAll('.sticky-element'); const observer = new IntersectionObserver( ([entry]) => { entry.target.classList.toggle('pinned', entry.intersectionRatio < 1); }, { threshold: [1, 0.01] }, ); stickyElements.forEach((sticky, i) => { if (sticky) { observer.observe(sticky); } });
.sticky-nav { position: sticky; top: -1px; z-index: 2; outline: 1px dashed black; } .sticky-element { position: sticky; top: 15px; z-index: 2; outline: 1px dashed orange; } .sticky-element.pinned { background: white; border-bottom: 1px solid #ccc; } .sticky-element.pinned { &:after { content: ' (pinned)'; } } .just-content { height: 100vh; display: flex; justify-content: center; align-items: center; background: #f8f8f8; }
<div class="just-content">I'm just normal element</div>
<nav class="sticky-nav">Sticky element just above</nav>
<div class="just-content">I'm just normal element</div>

  <div class="sticky-element">I'm sticky</div>
  <div class="just-content">I'm just normal element</div>
  <div class="sticky-element">I'm sticky 1</div>
  <div class="just-content">I'm just normal element</div>
  <div class="sticky-element">I'm sticky 2</div>
  <div class="just-content">I'm just normal element</div>

我添加了轮廓,以便您可以检查项目是否位于“主要”粘性元素后面/重叠。

所以观察者在这种情况下不起作用,因为我猜该项目实际上并没有离开视口。

所以问题是,这种情况有什么解决方法吗?也许基于容器?

我能够通过将
javascript css sticky
1个回答
0
投票
与 css 顶部属性值进行比较来实现它。当它们匹配时,就会粘起来

const stickyElements = document.querySelectorAll('.sticky-element'); const onScroll = () => { requestAnimationFrame(() => { stickyElements.forEach((sticky) => { if (sticky) { const elementCSSTop = parseInt(window.getComputedStyle(sticky, null).getPropertyValue('top')); sticky.classList.toggle('pinned', sticky.getBoundingClientRect().top === elementCSSTop); } }); }); }; window.addEventListener('scroll', onScroll);
.sticky-nav { position: sticky; top: -1px; z-index: 2; outline: 1px dashed black; } .sticky-element { position: sticky; top: 18px; z-index: 2; } .sticky-element.pinned { background: white; border-bottom: 1px solid #ccc; } .sticky-element.pinned { &:after { content: ' (pinned)'; } } .just-content { height: 100vh; display: flex; justify-content: center; align-items: center; background: #f8f8f8; }
<div class="just-content">I'm just normal element</div>
<nav class="sticky-nav">Sticky element just above</nav>
<div class="just-content">I'm just normal element</div>

<div class="sticky-element">I'm sticky</div>
<div class="just-content">I'm just normal element</div>
<div class="sticky-element">I'm sticky 1</div>
<div class="just-content">I'm just normal element</div>
<div class="sticky-element">I'm sticky 2</div>
<div class="just-content">I'm just normal element</div>

© www.soinside.com 2019 - 2024. All rights reserved.