【问题标题】:Visible intersectionObserver可见交叉口观察者
【发布时间】:2018-11-22 17:36:34
【问题描述】:

我正在尝试了解 Javascript 的 IntersectionObserver。

在阅读了几篇文章和文档后,我决定自己制作一个 CodePen 来尝试一下:IntersectionObserver CodePen

我想在顶部消息中显示“可见的块”。 CodePen“几乎”有效,但不完全有效。有时它显示正确的块,有时它不显示。

这是我的 JS:

let message = document.querySelector('#block-number');

// INTERSECTION OBSERVER STUFF
const io = new IntersectionObserver(entries => {
   if(entries[0].isIntersecting) {
    message.innerHTML = entries[0].target.textContent;
  }
}, {
    threshold: [.25]
});

// ELEMENTS TO OBSERVE
const blk1 = document.querySelector('#block1');
const blk2 = document.querySelector('#block2');
const blk3 = document.querySelector('#block3');
const blk4 = document.querySelector('#block4');
const blk5 = document.querySelector('#block5');
const blk6 = document.querySelector('#block6');

// START OBSERVING ELEMENTS
io.observe(blk1);
io.observe(blk2);
io.observe(blk3);
io.observe(blk4);
io.observe(blk5);
io.observe(blk6);

关于我做错了什么有什么想法吗?

我也尝试过(没有运气):

if(entries[0].intersectionRatio !== 0)

谢谢!

【问题讨论】:

    标签: javascript intersection-observer


    【解决方案1】:

    传递给 IntersectionObserved 的函数在相交状态发生变化时执行。那么当您在第 3 块并滚动一点以显示第 4 块时会发生什么?块 4 的交集发生了变化,因此消息也发生了变化。当您向上滚动时,第 4 块的交集再次更改,但它不进入 if 条件。另一方面,区块 3 的交叉点没有改变 - 它以前是可见的,即使不是完全可见,但它仍然可见。

    有几种方法可以解决此问题。 一种是定义相交比率,高于和低于该比率将被视为状态变化(传递选项哈希作为第二个参数,包含值 0 - 1 的 threshold 键,例如 0.5 表示 50% 可见性)

    您还可以为所有块添加相同的观察者,并在函数中遍历entries,检查哪个块具有最佳交叉率。

    【讨论】:

    • 你的意思是像我现在拥有的吗?仍然不完全工作! :( 请查看更改后的问题!
    • @LuisBento 尝试使用entries.forEach (entry) 而不是entries[0]
    【解决方案2】:

    您已将阈值设置为 25%。

    这样做的问题是,前一个块离开其最后 25% 的视口下一个块进入视口 25%。

    通过以下 console.log 很容易看到:

    console.log(entries[0].target.textContent, ": ", entries[0].intersectionRatio)
    

    let message = document.querySelector('#block-number');
    
    // INTERSECTION OBSERVER STUFF
    const io = new IntersectionObserver(entries => {
       if(entries[0].isIntersecting ) {
        console.log(entries[0].target.textContent, ": ", entries[0].intersectionRatio)
        message.innerHTML = entries[0].target.textContent;
      }
    }, {
        threshold: [.25]
    });
    
    // ELEMENTS TO OBSERVE
    const blk1 = document.querySelector('#block1');
    const blk2 = document.querySelector('#block2');
    const blk3 = document.querySelector('#block3');
    const blk4 = document.querySelector('#block4');
    const blk5 = document.querySelector('#block5');
    const blk6 = document.querySelector('#block6');
    
    // START OBSERVING ELEMENTS
    io.observe(blk1);
    io.observe(blk2);
    io.observe(blk3);
    io.observe(blk4);
    io.observe(blk5);
    io.observe(blk6);
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-family: roboto;
    }
    
    .center {
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    .container {
      background-color: #eee;
      width: 100%;
      height: 100%;
      min-height: 100vh;
    }
    
    .message {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      height: 80px;
      background-color: #ef9b8d;
      color: white;
    }
    
    .blocks {
      padding-top: 100px;
    }
    
    .block {
      height: 85vh;
      width: 90vw;
      margin: 0 auto 15vh;
      background-color: #999;
      color: white;
    }
    <div class="message center">Displaying &nbsp;<span id="block-number">Block 1</span></div>
      
      <div class="blocks">
        <div id="block1" class="block center">Block 1</div>
        <div id="block2" class="block center">Block 2</div>
        <div id="block3" class="block center">Block 3</div>
        <div id="block4" class="block center">Block 4</div>
        <div id="block5" class="block center">Block 5</div>
        <div id="block6" class="block center">Block 6</div>
      </div>

    要解决此问题,只需提高阈值。 (取决于有多少块需要进入视口以便您将其视为当前块)

    演示:

    let message = document.querySelector('#block-number');
    
    // INTERSECTION OBSERVER STUFF
    const io = new IntersectionObserver(entries => {
       if(entries[0].isIntersecting ) {
        console.log(entries[0].target.textContent, ": ", entries[0].intersectionRatio)
        message.innerHTML = entries[0].target.textContent;
      }
    }, {
        threshold: [.8] // raised the threshold
    });
    
    // ELEMENTS TO OBSERVE
    const blk1 = document.querySelector('#block1');
    const blk2 = document.querySelector('#block2');
    const blk3 = document.querySelector('#block3');
    const blk4 = document.querySelector('#block4');
    const blk5 = document.querySelector('#block5');
    const blk6 = document.querySelector('#block6');
    
    // START OBSERVING ELEMENTS
    io.observe(blk1);
    io.observe(blk2);
    io.observe(blk3);
    io.observe(blk4);
    io.observe(blk5);
    io.observe(blk6);
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-family: roboto;
    }
    
    .center {
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    .container {
      background-color: #eee;
      width: 100%;
      height: 100%;
      min-height: 100vh;
    }
    
    .message {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      height: 80px;
      background-color: #ef9b8d;
      color: white;
    }
    
    .blocks {
      padding-top: 100px;
    }
    
    .block {
      height: 85vh;
      width: 90vw;
      margin: 0 auto 15vh;
      background-color: #999;
      color: white;
    }
    <div class="message center">Displaying &nbsp;<span id="block-number">Block 1</span></div>
      
      <div class="blocks">
        <div id="block1" class="block center">Block 1</div>
        <div id="block2" class="block center">Block 2</div>
        <div id="block3" class="block center">Block 3</div>
        <div id="block4" class="block center">Block 4</div>
        <div id="block5" class="block center">Block 5</div>
        <div id="block6" class="block center">Block 6</div>
      </div>

    【讨论】:

      猜你喜欢
      • 2023-04-06
      • 1970-01-01
      • 2022-01-18
      • 2022-01-17
      • 2021-07-20
      • 2021-09-28
      • 2022-01-23
      • 1970-01-01
      相关资源
      最近更新 更多