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

Angular 5中如何在路由跳转至其他视图前执行动画?

完全可以做到!这其实是前端路由切换中很常见的动效需求,核心逻辑就是先把路由的默认跳转行为拦截下来,等当前视图的退出动画执行完毕后,再手动触发路由跳转。我给你拆解下具体实现思路,再结合主流框架举几个实用的例子:

核心步骤

  1. 拦截默认跳转:给路由链接绑定点击事件,阻止浏览器默认的页面跳转行为
  2. 触发退出动画:给当前视图元素添加预先定义好的动画类名,启动退出动效
  3. 监听动画完成:绑定transitionend或animationend事件,在动画结束的回调里手动执行路由跳转

Vue 项目示例(基于 Vue Router)

假设你用的是<router-link>组件,可以通过@click.prevent阻止默认跳转,然后在方法里处理动画和路由:

<template>
  <div ref="currentView" class="view-container">
    <!-- 路由链接,阻止默认跳转 -->
    <router-link to="/new-page" @click.prevent="handleAnimatedRoute">跳转到新页面</router-link>
    <!-- 视图内容 -->
  </div>
</template>

<script>
export default {
  methods: {
    handleAnimatedRoute(e) {
      const targetPath = e.currentTarget.getAttribute('to');
      const viewEl = this.$refs.currentView;
      
      // 添加退出动画类
      viewEl.classList.add('exit-slide-out');
      
      // 监听动画结束事件
      const onAnimationFinish = (event) => {
        // 只在目标属性动画完成后执行跳转(避免多次触发)
        if (event.propertyName === 'transform') {
          viewEl.removeEventListener('transitionend', onAnimationFinish);
          // 手动跳转路由
          this.$router.push(targetPath);
        }
      };
      
      viewEl.addEventListener('transitionend', onAnimationFinish);
    }
  }
}
</script>

<style scoped>
.view-container {
  transition: transform 0.4s ease-in-out;
}
.exit-slide-out {
  transform: translateX(-100%);
  opacity: 0;
}
</style>

React 项目示例(基于 React Router)

用普通<a>标签配合useNavigate钩子,拦截默认行为后手动跳转:

import { useNavigate } from 'react-router-dom';
import { useRef } from 'react';

function CurrentPage() {
  const navigate = useNavigate();
  const viewRef = useRef(null);

  const handleRouteClick = (e) => {
    e.preventDefault();
    const targetPath = e.currentTarget.href.split(window.location.origin)[1];
    
    // 启动退出动画
    viewRef.current.classList.add('fade-out');
    
    // 监听动画结束
    const finishAnimation = () => {
      viewRef.current.removeEventListener('animationend', finishAnimation);
      navigate(targetPath);
    };
    
    viewRef.current.addEventListener('animationend', finishAnimation);
  };

  return (
    <div ref={viewRef} className="page-container">
      <a href="/new-page" onClick={handleRouteClick}>跳转到新页面</a>
      {/* 页面内容 */}
    </div>
  );
}

// 对应的CSS
/*
.page-container {
  animation-duration: 0.3s;
}
.fade-out {
  animation-name: fadeOut;
}
@keyframes fadeOut {
  from { opacity: 1; }
  to { opacity: 0; transform: scale(0.95); }
}
*/

关键注意事项

  • 区分动画事件:如果用CSS transition做动画,监听transitionend;用CSS @keyframes做动画,监听animationend。也可以同时监听两个事件,避免遗漏。
  • 移除事件监听器:一定要在动画结束后移除监听器,防止内存泄漏。
  • 避免重复触发:如果动画包含多个属性变化(比如同时改opacity和transform),transitionend会触发多次,可以通过event.propertyName判断只在目标属性完成后执行跳转。

内容的提问来源于stack exchange,提问作者Michael Saly

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:03:06