IntersectionObserver 丢失观察到的元素
IntersectionObserver loses observed element
我正在尝试在我的 Angular 应用程序中使用 IntersectionObserver,但它没有按预期工作。我没有可重现的示例,因为这会影响高效的实施,也许这个简单的案例就足够了。所以我有一个通过 *ngFor 指令生成某些元素的视图:
app.component.html
<div *ngFor="let row of dataSource$ | async" #rows>
app.component.ts
@ViewChildren('rows') rows: QueryList<ElementRef<HTMLElement>>;
private observer: IntersectionObserver;
ngAfterViewInit(): void {
this.observer = new IntersectionObserver(entries => {
console.log(entries);
if (entries[0].isIntersecting) {
console.log('BottomElement is intersecting');
}
if (entries[1].isIntersecting) {
console.log('TopElement is intersecting');
}
}
this.rows.changes.subscribe(elements => {
this.observer.observe(elements.last.nativeElement);
this.observer.observe(elements.first.nativeElement);
});
}
所以我基本上是将生成的第一个和最后一个添加到 IntersectionObserver。如果我启动我的应用程序,一切正常,我得到以下控制台输出:
(2) [IntersectionObserverEntry, IntersectionObserverEntry]
TopElement is intersecting
但是一旦我开始向下滚动,一旦 TopElement 消失,IntersectionObservable 输出:
[IntersectionObserverEntry]
BottomElement is intersecting
ERROR TypeError: Cannot read properties of undefined (reading 'isIntersecting')
所以IntersectionObservable失去了要观察的TopElement。奇怪的是,BottomElement没有任何问题,所以上下滚动BottomElement一直被观察到。
知道问题出在哪里吗?
您总是希望有 2 个条目相交。当顶部元素离开视口区域而底部元素刚开始相交时会发生什么?我猜你在屏幕上只会有一个元素。因此,您无法访问 entries[]
上的元素,这些元素无法访问。
Intersection Observer API 允许您配置在以下任一情况发生时调用的回调:
目标元素与设备的视口或指定元素相交。出于 Intersection Observer API 的目的,该指定元素称为根元素或根。
第一次观察者最初被要求观察一个目标元素。
https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#intersection_observer_concepts_and_usage
但是,如果您只是阅读所得到的内容呢?即顶部相交,顶部离开,底部相交,底部离开。一个指令来帮助你怎么样?
private _callback = (entries, observer) => {
entries.forEach(entry => {
console.log(entry.isIntersecting ? this.elementName + 'I am visible' : this.elementName + 'I am not visible');
this.visibilityChange.emit(entry.isIntersecting ? 'VISIBLE' : 'HIDDEN')
});
};
<div enterTheViewportNotifier elementName="TOP ELEMENT" style="height: 100px; background-color: yellow">
I'll notify when I'm visible TOP ELEMENT
</div>
<div enterTheViewportNotifier elementName="BOTTOM ELEMENT" style="height: 100px; background-color: blue">
I'll notify when I'm visible BOTTOM ELEMENT
</div>
这是一个工作示例:https://stackblitz.com/edit/angular-ivy-3mkabk?file=src%2Fapp%2Fenter-the-view-port.directive.ts
我正在尝试在我的 Angular 应用程序中使用 IntersectionObserver,但它没有按预期工作。我没有可重现的示例,因为这会影响高效的实施,也许这个简单的案例就足够了。所以我有一个通过 *ngFor 指令生成某些元素的视图:
app.component.html
<div *ngFor="let row of dataSource$ | async" #rows>
app.component.ts
@ViewChildren('rows') rows: QueryList<ElementRef<HTMLElement>>;
private observer: IntersectionObserver;
ngAfterViewInit(): void {
this.observer = new IntersectionObserver(entries => {
console.log(entries);
if (entries[0].isIntersecting) {
console.log('BottomElement is intersecting');
}
if (entries[1].isIntersecting) {
console.log('TopElement is intersecting');
}
}
this.rows.changes.subscribe(elements => {
this.observer.observe(elements.last.nativeElement);
this.observer.observe(elements.first.nativeElement);
});
}
所以我基本上是将生成的第一个和最后一个添加到 IntersectionObserver。如果我启动我的应用程序,一切正常,我得到以下控制台输出:
(2) [IntersectionObserverEntry, IntersectionObserverEntry]
TopElement is intersecting
但是一旦我开始向下滚动,一旦 TopElement 消失,IntersectionObservable 输出:
[IntersectionObserverEntry]
BottomElement is intersecting
ERROR TypeError: Cannot read properties of undefined (reading 'isIntersecting')
所以IntersectionObservable失去了要观察的TopElement。奇怪的是,BottomElement没有任何问题,所以上下滚动BottomElement一直被观察到。
知道问题出在哪里吗?
您总是希望有 2 个条目相交。当顶部元素离开视口区域而底部元素刚开始相交时会发生什么?我猜你在屏幕上只会有一个元素。因此,您无法访问 entries[]
上的元素,这些元素无法访问。
Intersection Observer API 允许您配置在以下任一情况发生时调用的回调: 目标元素与设备的视口或指定元素相交。出于 Intersection Observer API 的目的,该指定元素称为根元素或根。 第一次观察者最初被要求观察一个目标元素。 https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#intersection_observer_concepts_and_usage
但是,如果您只是阅读所得到的内容呢?即顶部相交,顶部离开,底部相交,底部离开。一个指令来帮助你怎么样?
private _callback = (entries, observer) => {
entries.forEach(entry => {
console.log(entry.isIntersecting ? this.elementName + 'I am visible' : this.elementName + 'I am not visible');
this.visibilityChange.emit(entry.isIntersecting ? 'VISIBLE' : 'HIDDEN')
});
};
<div enterTheViewportNotifier elementName="TOP ELEMENT" style="height: 100px; background-color: yellow">
I'll notify when I'm visible TOP ELEMENT
</div>
<div enterTheViewportNotifier elementName="BOTTOM ELEMENT" style="height: 100px; background-color: blue">
I'll notify when I'm visible BOTTOM ELEMENT
</div>
这是一个工作示例:https://stackblitz.com/edit/angular-ivy-3mkabk?file=src%2Fapp%2Fenter-the-view-port.directive.ts