问题描述
我正在尝试在用户向下滚动时向页面添加元素。当最后一个元素完全显示时,我希望调用观察者回调,创建一个新元素,观察者设置为观察新元素,而不再观察当前目标。
function observerCallback(entries,observer) {
entries.forEach((entry) => {
const newDiv = document.createElement('div')
observer.observe(newDiv)
document.body.appendChild(newDiv)
observer.unobserve(entry.target);
});
}
但是,这不起作用,而且回调一直不断被调用,并产生了新的元素。我设置了一个codepen来演示此问题。
为什么会这样?
解决方法
您必须检查entry
是否可见(与容器相交)
if (entry.isIntersecting) {
//...
}
只有这样(或者如果阈值高于某个值),就会向DOM添加一个新元素。
let observer = new IntersectionObserver(observerCallback,{ threshold: 1.0 });
function observerCallback(entries,observer) {
entries.forEach((entry) => {
if (!entry.isIntersecting) {
return;
}
const newDiv = document.createElement('div')
observer.observe(newDiv)
document.body.appendChild(newDiv)
observer.unobserve(entry.target);
});
}
observer.observe(document.querySelector('div'))
div { height: 50px; background-color: red; margin-bottom: 20px }
<div></div>
,
仅仅是调用IntersectionObserver.observe(target)
会触发该target
的回调。
const observer = new IntersectionObserver(entries => {
console.log( 'new entry!',entries[0].target );
});
// wait a bit to show that it's really the call to observe() that does trigger the callback
setTimeout(()=> {
// even if not attached
const elem = document.createElement('div');
observer.observe( elem );
},2000);
所以unobserve
可以很好地工作,只是新观察到的元素本身会触发新的回调调用。
不知道您到底想做什么,很难告诉您如何修复代码,但这应该可以帮助您找到正确的路线,也许您只是在寻找isIntersecting
属性,因此当不再显示最后一个元素时停止。
let observer = new IntersectionObserver(observerCallback,observer) {
entries.forEach((entry) => {
if( !entry.isIntersecting ) {
return;
}
const newDiv = document.createElement('div')
observer.observe(newDiv)
document.body.appendChild(newDiv)
observer.unobserve(entry.target);
});
}
observer.observe(document.querySelector('div'))
div {
height: 20px;
background-color: red;
margin-bottom: 5px;
}
<div></div>
,
这仅仅是您执行功能的顺序吗?由于某些原因,CodePen无法在我的iPad上运行,因此我暂时无法测试。
function observerCallback(entries,observer) {
entries.forEach((entry) => {
const newDiv = document.createElement('div')
observer.unobserve(entry.target)
document.body.appendChild(newDiv)
observer.observe(newDiv)
});
}