Angular中如何判断所有子组件视图初始化完成及页面图片加载完成
Angular 路由页全量资源加载状态判断方案
1. 判断所有嵌套组件视图全部初始化完成
不需要给每个子组件硬编码生命周期钩子,可通过Angular全局内置的ApplicationRef结合路由事件实现:
- 核心逻辑:
ApplicationRef.isStable是一个Observable,会在应用内所有同步/异步任务执行完成、变更检测循环全部结束时发射true,此时对应当前路由下所有层级的子组件都已完成视图初始化。 - 代码示例:
import { ApplicationRef, Component, OnDestroy } from '@angular/core'; import { NavigationEnd, Router } from '@angular/router'; import { filter, take, takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; @Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent implements OnDestroy { private destroy$ = new Subject<void>(); constructor( private router: Router, private appRef: ApplicationRef ) { this.listenComponentAllInit(); } private listenComponentAllInit(): void { // 监听路由导航完成事件 this.router.events.pipe( filter(e => e instanceof NavigationEnd), takeUntil(this.destroy$) ).subscribe(() => { // 等待应用状态稳定,即所有组件初始化、变更检测完成 this.appRef.isStable.pipe( filter(isStable => isStable), take(1) ).subscribe(() => { console.log('当前路由所有组件视图已全部初始化完成:', new Date()); }); }); } ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); } }
注意:该方案默认会忽略未进入变更检测的懒加载组件,符合常规路由渲染逻辑。
2. 判断当前路由页面所有图片加载完成
在上面组件全部初始化完成的基础上,遍历DOM中所有img元素监听加载状态即可:
- 核心逻辑:拿到页面所有img标签,统一监听
load和error事件,所有事件触发完毕即代表图片全部加载完成(加载失败的图片也会触发error事件,不会阻塞判断)。 - 代码示例:
// 接上面listenComponentAllInit方法内的stable回调 this.appRef.isStable.pipe( filter(isStable => isStable), take(1) ).subscribe(() => { console.log('当前路由所有组件视图已全部初始化完成:', new Date()); this.checkAllImagesLoaded(); }); // 新增图片加载检测方法 private checkAllImagesLoaded(): void { const imgs = Array.from(document.getElementsByTagName('img')); // 没有图片直接判定完成 if (imgs.length === 0) { console.log('当前页面无图片,加载完成'); return; } let loadedCount = 0; const checkComplete = () => { loadedCount++; if (loadedCount === imgs.length) { console.log('当前页面所有图片已加载完成:', new Date()); } }; imgs.forEach(img => { // 已经加载完成的图片直接计数 if (img.complete) { checkComplete(); } else { img.addEventListener('load', checkComplete, { once: true }); img.addEventListener('error', checkComplete, { once: true }); } }); }
提示:如果页面存在动态插入的图片(比如接口返回后才渲染的图片),可在动态渲染逻辑触发后重新调用
checkAllImagesLoaded方法检测。
内容的提问来源于stack exchange,提问作者byCoder
相关产品推荐
相关产品推荐

