You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中如何监听指定动画的元素状态变化并识别:enter/:leave状态

实现指定动画key的元素状态监听方案

这里以Vue生态的动画场景为例,通过封装全局动画事件管理器+动画钩子上报的方式就能实现你要的订阅式监听效果,具体实现步骤如下:

步骤1:实现全局动画管理单例

创建animationObserver.js文件,实现你需要的on、subscribe接口能力:

class AnimationObserver {
  constructor() {
    // 按动画key存储订阅回调列表
    this.subscriberMap = new Map()
  }

  // 绑定要监听的动画key
  on(animationKey) {
    if (!this.subscriberMap.has(animationKey)) {
      this.subscriberMap.set(animationKey, [])
    }
    return {
      // 注册回调,返回取消订阅的方法
      subscribe: (callback) => {
        this.subscriberMap.get(animationKey).push(callback)
        return () => {
          const callbackList = this.subscriberMap.get(animationKey)
          const idx = callbackList.indexOf(callback)
          if (idx > -1) callbackList.splice(idx, 1)
        }
      }
    }
  }

  // 内部方法:动画触发时上报事件
  emit(animationKey, targetEl, animationState) {
    if (this.subscriberMap.has(animationKey)) {
      this.subscriberMap.get(animationKey).forEach(cb => {
        cb({
          el: targetEl,
          state: animationState
        })
      })
    }
  }
}

// 导出全局单例
export const animations = new AnimationObserver()

步骤2:在动画触发钩子中上报状态

根据你使用的动画实现方式,在对应的动画生命周期钩子中调用emit方法上报状态即可,两种常见场景的处理方式如下:

  • 如果你用Vue原生<Transition>组件实现动画,可以封装一个全局的通用动画组件代替原生组件,自动上报状态:
<script setup>
import { animations } from './animationObserver'
const props = defineProps(['name'])
</script>

<template>
  <Transition
    :name="name"
    @enter="(el) => animations.emit(name, el, 'enter')"
    @leave="(el) => animations.emit(name, el, 'leave')"
    <!-- 可根据需要扩展动画结束、动画取消等状态的上报 -->
    @after-enter="(el) => animations.emit(name, el, 'enter-end')"
    @after-leave="(el) => animations.emit(name, el, 'leave-end')"
    v-bind="$attrs"
  >
    <slot />
  </Transition>
</template>

后续使用时把原来的<Transition name="fadeInOut">替换为这个封装组件即可。

  • 如果你用自定义指令实现@fadeInOut这类绑定语法,直接在指令对应的元素挂载/卸载、动画触发的钩子中调用animations.emit上报对应状态即可。

调用效果

和你期望的用法完全一致:

import { animations } from './animationObserver'

// 监听fadeInOut动画
const unsubscribe = animations.on('fadeInOut').subscribe((info) => {
  // info.el是当前触发动画的DOM元素,info.state是动画状态(enter/leave等)
  console.log(`元素${info.el.id}触发了${info.state}动画`)
})

// 不需要监听时调用取消订阅,避免内存泄漏
// unsubscribe()

内容的提问来源于stack exchange,提问作者Mahdi Zarei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 20:45:07