Angular 6路由切换动画在Edge/IE中未移除旧路由视图
解决Angular 6升级后IE/Edge路由动画旧路由残留问题
我之前帮开发者处理过完全相同的问题——Angular 5里正常的路由动画,升级到6后在IE和Edge里就出现旧路由残留的情况,Chrome却完全没问题。这本质上是IE/Edge对Web Animations API的兼容性差异,加上Angular 6在动画结束后对DOM元素的处理逻辑有细微调整,哪怕你已经引入了polyfill,特定的定位+动画组合还是会出问题。下面是具体的解决方法:
1. 修改动画代码,确保旧路由动画结束后彻底隐藏
你的当前代码只是把旧路由移出了可视区域,但在IE/Edge中,position: fixed的元素就算被translate到屏幕外,仍然会留在DOM里(视觉上就表现为残留)。我们需要在动画结束后给旧路由加上display: none,让它彻底从UI中消失:
import { trigger, style, animate, transition, query, group } from '@angular/animations'; export const RouterAnimation = trigger('routerAnimation', [ transition('* <=> *', [ // 新路由初始状态:固定定位在右侧,完全不可见 query(':enter', style({ position: 'fixed', width: '100%', transform: 'translateX(100%)', opacity: 0 }), {optional: true}), // 旧路由动画:先滑出左侧,动画结束后立即隐藏 query(':leave', group([ animate('500ms ease', style({ position: 'fixed', width: '100%', transform: 'translateX(-100%)', opacity: 0 })), // 延迟500ms(和滑出动画时长一致)后设置display:none animate('0ms 500ms', style({ display: 'none' })) ]), {optional: true}), // 新路由滑入动画:从右侧移到屏幕内,渐显 query(':enter', animate('500ms ease', style({ opacity: 1, transform: 'translateX(0%)' })), {optional: true}), ]) ]);
这里用group把两个动画组合起来:先执行滑出动画,等滑完之后再设置display: none,完美解决旧路由残留的问题。
2. 确认polyfill的完整性(别漏了关键的Web Animations polyfill)
虽然你说已经加了polyfill,但Angular 6对IE的支持要求更严格,一定要确保polyfills.ts里包含以下内容:
// IE9-11基础polyfill import 'core-js/es6/symbol'; import 'core-js/es6/object'; import 'core-js/es6/function'; import 'core-js/es6/parse-int'; import 'core-js/es6/parse-float'; import 'core-js/es6/number'; import 'core-js/es6/math'; import 'core-js/es6/string'; import 'core-js/es6/date'; import 'core-js/es6/array'; import 'core-js/es6/regexp'; import 'core-js/es6/map'; import 'core-js/es6/weak-map'; import 'core-js/es6/set'; // IE10-11 SVG元素NgClass支持需要的polyfill import 'classlist.js'; // 记得先执行npm install --save classlist.js // 关键!IE/Edge不支持原生Web Animations API,必须加这个 import 'web-animations-js'; // 先执行npm install --save web-animations-js
很多人容易漏掉web-animations-js,这是IE/Edge正常运行Angular动画的核心依赖。
3. 检查路由出口的动画绑定是否正确
最后再确认一下你的根组件(比如app.component.html)里路由出口的绑定:
<router-outlet #outlet="outlet" [@routerAnimation]="prepareRoute(outlet)"></router-outlet>
对应的app.component.ts里要有这个辅助函数(如果不需要基于路由状态的动画,也可以直接返回true):
prepareRoute(outlet: RouterOutlet) { return outlet && outlet.activatedRouteData && outlet.activatedRouteData['animation']; }
额外排查小技巧
- 打开IE/Edge的开发者工具,看Console里有没有JS报错,比如polyfill加载失败或者动画模块的错误,这往往能快速定位问题。
- 如果还是有问题,可以试试把
position: fixed改成position: absolute,同时给父容器(比如app-root)加上position: relative; overflow: hidden; height: 100vh;,某些情况下IE对fixed的动画支持确实不如absolute稳定。
内容的提问来源于stack exchange,提问作者Steve Fitzsimons
相关产品推荐
相关产品推荐

