【问题标题】:IntersectionObserver, how to Intersect full height of elements observing using JavascriptIntersectionObserver,如何使用 Javascript 观察元素的全高度相交
【发布时间】:2022-07-29 07:54:23
【问题描述】:

你好,我有一个问题。我想与选定的观察元素高度完全相交。不是下图中的一半或双相交,当我滚动时,两个元素已经相交我只想要滚动时谁是全高

这是我的 HTML 代码

<ul>
  <li><a href="#one" class="active">P1</a></li>
  <li><a href="#two">P2</a></li>
  <li><a href="#three">P3</a></li>
  <li><a href="#four">P4</a></li>
</ul>
<div id="one">
  <p>P1 </p>
  <section>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
  quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
  consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
  cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
  proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</section>
</div>

<div id="two">
  <p>P2 </p>
  <section>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
  quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
  consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
  cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
  proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</section>
</div>

<div id="three">
  <p>P3 </p>
  <section>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
  quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
  consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
  cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
  proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</section>
</div>

<div id="four">
  <p>P4 </p>
  <section>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
  quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
  consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
  cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
  proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</section>
</div>

这是我的 Javascript 代码

  let observer = new IntersectionObserver(beTouching)

  document.querySelectorAll('div').forEach(div=>{
    observer.observe(div)
  })

  function beTouching(elements){
    elements.forEach(element=>{
      if(element.isIntersecting&&element.boundingClientRect.height){
        console.log(element.target)
         let id  = element.target.getAttribute('id')
         document.querySelector('ul li a[href*='+id+']').classList.add('active');
      }else{
        let id  = element.target.getAttribute('id')
         document.querySelector('ul li a[href*='+id+']').classList.remove('active');
      }
    })
  }

这是我的 Css 代码

*{
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  text-decoration: none;
  scroll-behavior: smooth;

}
body{

}
div#one{
  background: cornflowerblue;
  height: 100vh;
}
div#two{
  background: coral;
  height: 100vh;
}
div#three{
  background: pink;
  height: 100vh;
}
div#four{
  background: skyblue;
  height: 100vh;
}
.active{
  background: red !important;
  color: white !important;
  padding: 20px;
}
ul{
  height: 50px;
  width: 100%;
  background: green;
  display: flex;
  list-style-type: none;
  justify-content: space-around;
  align-items: center;
  position: sticky;
  top: 0px;
}

【问题讨论】:

    标签: javascript


    【解决方案1】:

    据我了解,您希望您的导航链接在它们链接到的部分在视口中可见时突出显示,并且避免同时突出显示两个导航链接。

    您可以通过稍作修改并使用交叉点观察者的rootMargin 来实现这一点。

    路口观察者回调:

    function beTouching (elements) {
      elements.forEach(element=> {
        const id = element.target.getAttribute('id')
        const menuLink = document.querySelector(`ul li a[href='#${id}']`)
    
        if(element.isIntersecting) {
          document.querySelector('ul li a.active').classList.remove('active')
          menuLink.classList.add('active')
        }
      })
    }
    

    在您的交叉点观察者定义中:

    const observer = new IntersectionObserver(beTouching, {
      rootMargin: '-50% 0px'
    })
    

    说明:

    使用负的rootMargin 作为顶部和底部边距,您基本上是在垂直“减少”相交部分,因此,可以避免在视口中部分可见的两个部分同时相交。现在,通过在没有这行代码的情况下执行此操作:

     if(element.isIntersecting) {
          document.querySelector('ul li a.active').classList.remove('active')
          menuLink.classList.add('active')
        }
    

    会发生的情况是,在您滚动时的中间某个点,没有任何部分会相交,因此不会突出显示导航链接,这是一种不受欢迎的行为。因此,您设置了一个条件,即仅当元素相交时,然后继续从与先前相交的部分对应的 a 标记中删除 active 类,并将 active 添加到当前相交的部分相交。

    注意:您可以尝试使用负上边距和下边距来找到最适合您的组合。如果您尝试不同的值,请确保它们的总和始终等于 100%(例如,-30% 顶部,-70% 底部)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-15
      • 1970-01-01
      • 2022-09-12
      • 2020-12-10
      • 1970-01-01
      • 1970-01-01
      • 2022-01-11
      • 2021-02-08
      相关资源
      最近更新 更多