首页 > 解决方案 > Intersection Obsser 在 Angular 7 应用程序中冻结 IE11

问题描述

我创建了一个 Angular 7 应用程序并使用 Intersection Observer 来延迟加载一些项目。它在 Chrome、Mozilla 甚至 Edge 中都可以轻而易举地工作。但是在 IE11 中,当延迟加载启动和交叉点观察器启动时,应用程序会冻结。我在 polyfills.ts 中添加了 import 'intersection-observer' 以支持 IE11。我对这种行为感到困惑。

  intersectionObserverForTableRow() {
    const selectedNodeLists = document.getElementsByClassName('tableDataRow');

    const tableIntersectionObserver = new IntersectionObserver((entries, tableIntersectionObserver) => {
      entries.forEach((entry) => {
        if (!this.hasNextPage) {
          this.showShimmerRows = false;
          tableIntersectionObserver.disconnect();
        }
        if (entry.isIntersecting) {
          const el = entry.target;
          // console.log(el.id, ('lazyLoadedObserver' + (this.currentTableContent.length - 1)))
          if (el.id === ('lazyLoadedObserver' + (this.currentTableContent.length - 1))) {
            // console.log('inside');
            // this.currentTableContent = this.currentTableContent.concat(this.setDummyDataForTableRowShimmer());
            this.setDummyDataForTableRowShimmer();
            this.pageNumber++;
            this.loadNextSetOfData.emit(this.pageNumber);
            // console.log(this.currentTableContent)
            // setTimeout(() => {
            //   this.triggerObserver(selectedNodeLists, tableIntersectionObserver)
            // }, 10);
            tableIntersectionObserver.unobserve(entry.target);
          }
        }
      });
    });

    this.triggerObserver(selectedNodeLists, tableIntersectionObserver);
  }

标签: javascriptangulartypescriptinternet-explorer-11intersection-observer

解决方案


编辑

我发现即使将下面提到的属性设置为 false IE 在 IO polyfill 处于活动状态时滚动也非常慢。最后我的解决方案是使用去抖滚动事件并在那里处理我的逻辑。我创建了一个滚动指令来处理这个问题。

private setScroller(scroller: CdkScrollable) {
  this.scroller = scroller;
  this.scroller.elementScrolled().subscribe(() => {
    this.scrolled();
  });
}

@debounce() // this is a debounce decorater that only triggers if there are no events for over 300ms
private scrolled() {
  // dispatch an event to the SETTER to get the componentId
  if (this.isIE11) {
    this.callIEFunction();
  }
}

使用@HostListener这个也减慢了我的 IE 速度。


所有这些其他答案都以某种方式错过了他为 IE 使用 polyfill 的点,因为 IE 不支持它。

但是,如果您使用 W3C 的官方交叉点观察者 polyfill,如果您尝试激活它,它将冻结 IE。

我有同样的错误(首先发现了这个问题),但后来我在文档中发现了一个小细节:

忽略 DOM 更改
您还可以选择在 DOM 更改时不检查交叉点,方法是将观察者的USE_MUTATION_OBSERVER属性设置为false

原始 IO 无法做到这一点(因为它开箱即用),因此很容易错过。但显然 w3c 的实现也检查了 dom 突变。

频繁更改 dom 的 Angular(我猜还有 react 和其他框架)可以冻结 IE。其他浏览器支持 IO 开箱即用,因此从不使用 polyfill。

长话短说,这对我有用:

var io = new IntersectionObserver(callback);
io.USE_MUTATION_OBSERVER = false;

文档还提到您可以全局禁用此功能,但这对我来说并没有真正起作用。

IntersectionObserver.prototype.USE_MUTATION_OBSERVER = false; // Globally (didn't work for me) 

推荐阅读