Angular 4加载器优化:等待所有资源(含图片)加载完成再停止
解决方案:处理Angular中图片资源加载完成后的加载器状态
首先,你遇到的无法在load事件回调中访问isLoading的问题,本质是JavaScript中this指向的问题:你用了普通的function作为回调,此时this指向的是window对象,而不是你的Angular组件实例。解决这个问题最直接的方式是改用箭头函数,它会继承外层作用域的this,也就是你的组件实例:
isLoading: boolean; ngOnInit() { this.isLoading = true; this.checkIfLoaded(); } checkIfLoaded() { // 先检查页面是否已经加载完成,避免事件错过触发 if (document.readyState === 'complete') { this.isLoading = false; return; } // 改用箭头函数,保证this指向组件 window.addEventListener("load", (event) => { console.log("All resources finished loading!"); this.isLoading = false; }); }
不过,window.load事件是等待**整个页面所有资源(包括脚本、样式、所有图片)**加载完成,这可能不是最精准的方案——如果你的页面还有其他无关资源,会导致加载器关闭延迟。针对你的场景(接口返回图片URL列表,仅需等待这些图片加载完成),推荐更精准的实现方式:
精准监听目标图片加载完成
- 在组件中维护一个已加载图片的计数器,以及图片列表:
isLoading: boolean; imageUrls: string[] = []; loadedImageCount = 0; ngOnInit() { this.isLoading = true; // 假设这是你的HTTP请求获取图片URL this.imageService.getImageUrls().subscribe(urls => { this.imageUrls = urls; // 图片URL拿到后,开始监听每张图片的加载 this.monitorImageLoads(); }); } monitorImageLoads() { if (this.imageUrls.length === 0) { this.isLoading = false; return; } this.imageUrls.forEach(url => { const img = new Image(); img.src = url; // 监听单张图片加载完成 img.onload = () => { this.loadedImageCount++; // 所有图片都加载完成后关闭加载器 if (this.loadedImageCount === this.imageUrls.length) { this.isLoading = false; } }; // 处理图片加载失败的情况,避免加载器一直显示 img.onerror = () => { this.loadedImageCount++; if (this.loadedImageCount === this.imageUrls.length) { this.isLoading = false; } }; }); }
- 模板中正常渲染图片即可:
<ng-container *ngIf="isLoading"> <app-spinner></app-spinner> </ng-container> <div *ngIf="!isLoading"> <img *ngFor="let url of imageUrls" [src]="url" alt="content image"> </div>
这种方式只会等待你从接口获取的图片加载完成,不会受页面其他资源影响,体验更精准。同时处理了图片加载失败的情况,避免加载器一直停留在页面上。
额外注意点(针对Angular 4.4)
- 如果你使用
ChangeDetectionStrategy.OnPush,可能需要手动触发变更检测:在设置this.isLoading = false后,注入ChangeDetectorRef并调用this.cdRef.markForCheck()。 - 记得在组件销毁时移除事件监听,避免内存泄漏:比如对于
window.load的监听,要在ngOnDestroy中调用window.removeEventListener。
内容的提问来源于stack exchange,提问作者hzbarkan
相关产品推荐
相关产品推荐

