如何在Angular 4.6应用中引入jQuery加载器?加载图失效求解决
嘿,作为Angular新手遇到这种问题太正常啦!先给你明确结论:嵌套路由确实是触发这个问题的场景之一,但核心原因是jQuery的DOM操作时机和Angular的单页应用机制不匹配。下面我给你详细拆解原因和解决方案:
为什么你的代码没生效?
你用的$(window).on('load')是jQuery监听整个页面首次加载完成的事件,但Angular是单页应用(SPA)——包括嵌套路由在内的所有路由切换,都不会重新刷新整个页面,只会在当前页面内更新DOM内容。这就意味着,你的这段加载动画逻辑只会在应用第一次启动时执行一次,之后不管怎么切换嵌套路由,它都不会再触发了,自然看不到效果。
解决方案:用Angular路由事件代替jQuery的window.load
既然Angular路由切换不会触发页面重载,那我们就直接监听Angular的路由状态变化来控制加载动画,不管是一级路由还是嵌套路由,都能完美覆盖。这里给你两种方案,一种是保留jQuery操作(过渡用),另一种是更符合Angular风格的写法(推荐):
方案1:结合jQuery和Angular路由事件
在你的根组件(比如app.component.ts)里注入Router,监听路由的开始和结束事件:
import { Component, OnInit } from '@angular/core'; import { Router, NavigationStart, NavigationEnd } from '@angular/router'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { constructor(private router: Router) {} ngOnInit() { this.router.events.subscribe(event => { // 路由开始切换时,显示加载器 if (event instanceof NavigationStart) { $('#loader').show(); $('#loader-wrapper').show(); $('body').css({ 'overflow': 'hidden' }); } // 路由切换完成后,隐藏加载器 else if (event instanceof NavigationEnd) { $('#loader').fadeOut(); $('#loader-wrapper').delay(350).fadeOut('slow'); $('body').delay(350).css({ 'overflow': 'visible' }); } }); } }
方案2:纯Angular风格(推荐,避免直接操作DOM)
尽量不要在Angular里用jQuery直接操作DOM,而是通过数据绑定来控制元素的显示隐藏,更符合Angular的设计理念:
- 在根组件模板(
app.component.html)中,用*ngIf绑定一个布尔变量来控制加载器的显示:
<!-- 加载器元素 --> <div id="loader-wrapper" *ngIf="isLoading"> <div id="loader"></div> </div> <!-- 你的路由出口 --> <router-outlet></router-outlet>
- 在
app.component.ts中监听路由事件,更新isLoading变量:
import { Component, OnInit } from '@angular/core'; import { Router, NavigationStart, NavigationEnd } from '@angular/router'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { isLoading = false; constructor(private router: Router) {} ngOnInit() { this.router.events.subscribe(event => { if (event instanceof NavigationStart) { this.isLoading = true; document.body.style.overflow = 'hidden'; } else if (event instanceof NavigationEnd) { // 延迟350ms再隐藏,和你原来的delay逻辑一致 setTimeout(() => { this.isLoading = false; document.body.style.overflow = 'visible'; }, 350); } }); } }
关于嵌套路由的补充说明
嵌套路由切换时,父组件不会重新初始化,所以如果你的加载逻辑写在父组件的ngOnInit或者window.load里,确实不会触发。但用上面的路由事件监听,只要是任何路由(包括嵌套路由)发生变化,NavigationStart和NavigationEnd都会触发,就能正确控制加载动画了。
内容的提问来源于stack exchange,提问作者bhaumik shah

