Ionic v5 Android端.fadeInBottom类动画偶发两次触发问题咨询
问题根因分析
你遇到的Android端偶发两次触发的问题,主要来自两个常见的Ionic兼容问题:
- 部分Android系统webview下,Ionic的
ionViewDidEnter生命周期存在偶发重复回调的问题,尤其是页面带转场动画、或者快速切页再切回时概率出现 - 当前动画实现没有做防重入判断,也没有清理上一次未完成的动画实例,重复触发时会叠加执行两次
修复方案
第一步:调整animations.service.ts,增加防重入、实例清理逻辑
// 增加变量存储当前运行的动画实例 private runningAnimations: any[] = []; private isAnimating = false; async fadeInBottom(elements: HTMLElement[]) { // 防重入:已经在跑动画直接返回 if (this.isAnimating) return false; this.isAnimating = true; // 先清理之前残留的动画实例 this.runningAnimations.forEach(anim => anim.destroy()); this.runningAnimations = []; const animations = elements.map((el, i) => { const anim = this.animaitionCtrl.create() .addElement(el) .duration(150) .delay(i * 25) .fromTo('opacity', 0,1) .fromTo('transform', 'translateY(30px)', 'none'); this.runningAnimations.push(anim); return anim.play(); }); try { await Promise.all(animations); return true; } finally { // 不管动画成功失败都重置状态 this.isAnimating = false; } }
第二步:调整页面调用逻辑,用Angular ViewChildren获取当前页元素,避免全局查找误拿到其他页面残留元素
// 页面ts文件中增加ViewChildren查询 import { ViewChildren, QueryList, ElementRef } from '@angular/core'; @ViewChildren('.fadeInBottom', { read: ElementRef }) fadeElements: QueryList<ElementRef>; async ionViewDidEnter() { // 转成原生元素数组传入service const elements = this.fadeElements.map(item => item.nativeElement); if (elements.length === 0) return; await this.animationsService.fadeInBottom(elements); }
第三步:补充全局CSS,设置元素初始状态,避免动画前闪屏
.fadeInBottom { opacity: 0; transform: translateY(30px); }
额外可选优化
如果仍有偶发问题,可以给ionViewDidEnter的调用加30-50ms的延迟,避开Android webview生命周期回调的冲突时段:
async ionViewDidEnter() { setTimeout(async () => { const elements = this.fadeElements.map(item => item.nativeElement); if (elements.length === 0) return; await this.animationsService.fadeInBottom(elements); }, 30); }
内容的提问来源于stack exchange,提问作者user11373613
相关产品推荐
相关产品推荐

