javascript - 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);
}
解决方案
编辑
我发现即使将下面提到的属性设置为 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)
推荐阅读
- http - 检查未知/远程服务器是否支持 HTTPS
- java - 如何在有偏权重的 x 变量之间划分总值 1
- node.js - 我想学习如何处理异步代码的Node js代码
- tensorflow - TensorFlow 不适用于 Python 3.7、Mac OS 和 Pycharm
- java - 拦截传入消息并将其记录到端点
- html - Angular 版本 6 空白页面和 HTML 渲染错误没有错误
- jenkins - Jenkins Kubernetes 插件:声明式管道和 pod 模板继承
- javascript - 如何使用赛普拉斯从本地上传文件
- matlab - MATLAB:找到离散傅里叶变换的更快方法
- python - 如何比较 SQL Server 和 Postgres 中两个表列的哈希值?