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