我正在尝试了解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)
谢谢!
答案 0 :(得分:0)
当交叉点状态改变时,执行传递给IntersectionObserved的函数。那么当您在第3块并滚动一点以便显示第4块时会发生什么?块4的交叉点发生变化,因此消息发生了变化。当您向后滚动时,交叉路口将再次更改为块4,但它不会进入if条件。另一方面,块3的交叉点没有改变 - 之前可见,即使不完全,它仍然可见。
有几种方法可以解决这个问题。
一种是定义交叉比率,并且在该比率之上和之下将被视为状态的变化(将选项散列作为第二参数,包含值为0-1的threshold
键,例如0.5为50%可见性)< / p>
您还可以为所有块添加相同的观察者,并在函数中迭代entries
,检查哪个块具有最佳交叉比。
答案 1 :(得分:0)
您已将阈值设置为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 <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 <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>