前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库CSS transitionend 事件 propertyName 判断
CSS动画与视觉

transitionend 事件怎么判断是哪个属性结束的?过渡被取消还会触发吗?

每个被过渡的属性结束时都会独立触发一次 transitionend,通过 event.propertyName 就能知道是哪个属性完成了。如果过渡中途被取消(比如 class 被撤掉),不会触发 transitionend,而是触发 transitioncancel。

前端进阶之旅 · 一题精讲更新于 2026.09.29
CSS#动画与视觉#动画
先看核心答案读代码示例
理解线索

过渡事件的三个阶段

  1. transitionrun过渡开始前触发,delay 期间就已触发
  2. transitionend过渡正常播完后触发,每个属性各一次
  3. transitioncancel过渡中途被取消时触发,不会再有 end

简写属性不会出现在 propertyName 里。写 transition: all .3s,触发的事件里 propertyName 是 opacity、transform 这样的单一属性名。

核心回答

先记住这个答案

浏览器为每个参与过渡的属性独立触发 transitionend 事件。事件对象的 propertyName 属性告诉你是哪个属性完成了过渡,elapsedTime 告诉你这段过渡花了多少秒。如果过渡中途被取消,比如在动画进行中把触发过渡的 class 移除了,浏览器不会触发 transitionend,而是触发 transitioncancel。

  • propertyName 标识结束的过渡属性
  • 多属性过渡会触发多次,每个属性各一次
  • 过渡被打断触发的是 transitioncancel
  • transitionend 冒泡,可在容器监听

一个按钮同时过渡两个属性的场景

假设一个按钮 hover 时同时改变 opacity 和 transform,过渡时长不同。鼠标移上去后会先后收到两次 transitionend,快的先到,慢的后到。在 JS 里如果只想在「全部过渡完成」后做某件事,就需要借助 propertyName 来判断。

监听特定属性结束CSS
.btn {
  opacity: 1;
  transform: scale(1);
  /* opacity 200ms 先结束,transform 400ms 后结束 */
  transition: opacity 200ms ease, transform 400ms ease;
}
.btn:hover {
  opacity: 0.8;
  transform: scale(1.05);
}

这段 CSS 在 hover 时会产生两次 transitionend。如果你在 JS 里用 addEventListener('transitionend', handler) 监听,handler 会被调用两次。第一次 event.propertyName 是 opacity,第二次是 transform。想等全部结束再做动作,最简单的办法是只判断最后结束的那个属性名。

过渡取消时事件的变化

过渡进行到一半时,如果触发过渡的条件消失了,浏览器会触发 transitioncancel,然后属性值会立刻(或反向过渡)回到初始状态。这时不会再触发 transitionend。

比如一个展开面板,过渡到一半时用户点了收起按钮。代码里如果用 transitionend 来做「展开完成后插入内容」之类的操作,这个回调就永远不会执行。所以依赖 transitionend 做流程控制的代码,必须同时处理 transitioncancel,否则状态会卡住。

一个更稳妥的做法JavaScript
el.addEventListener('transitionend', onDone)
el.addEventListener('transitioncancel', onDone) // 取消时也要清理状态

function onDone(e) {
  if (e.propertyName !== 'transform') return // 只关心 transform
  el.removeEventListener('transitionend', onDone)
  el.removeEventListener('transitioncancel', onDone)
  // 做后续操作
}

同时监听两个事件,保证无论过渡正常结束还是被取消,后续逻辑都能执行。

事件冒泡带来的便利和陷阱

transitionend 是会冒泡的。在一个列表容器上监听,所有子元素的过渡结束都会冒到容器上来。这在做列表动画时很方便,不用给每个子元素单独绑事件。但反过来说,如果容器自身也有过渡,就会混在一起。判断事件来源时用 event.target 确认是哪个元素触发的。

回答前,多想一步

容易答错的地方

以为过渡取消后还会触发 transitionend
不会。过渡被取消后触发的是 transitioncancel。如果代码里只监听了 transitionend 来做状态切换,取消场景下状态就会卡死。
以为简写属性名会出现在 propertyName 里
写 transition: all .3s,触发的事件里 propertyName 不会是 all,而是每个实际发生变化的单一属性名,比如 background-color 而不是 background。
试着用自己的话回答

面试官还会怎么问?

transitionstart 和 transitionrun 有什么区别?

transitionrun 在过渡被创建时就触发,即使有 transition-delay 也会立刻触发。transitionstart 要等到 delay 结束、过渡真正开始播放时才触发。如果 delay 是 0,两者几乎同时。

怎么用 Promise 封装等待过渡结束?

可以写一个函数,内部 new Promise,在 resolve 里移除监听。注意要同时处理 transitioncancel 的情况,否则 Promise 可能永远 pending。

animation 的事件和 transition 的事件有什么不同?

@keyframes 动画用的是 animationend、animationstart、animationiteration 这组事件。animationiteration 在每次循环结束时触发,这是 transition 没有的,因为 transition 不支持循环播放。

从一道题,走向一组知识

把知识连起来

动画与视觉

过渡进行到一半又改了目标值,浏览器怎么处理?

过渡被中断后浏览器从当前插值点开始新过渡,这个机制决定了 transitioncancel 的触发时机。

动画与视觉

怎么让一个元素的 width 和 opacity 用不同的过渡时长和缓动?

多属性不同时长时,transitionend 会分批触发,理解它才能写出正确的监听逻辑。

参考资料

  • CSS:动画与视觉参考资料

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 一个按钮同时过渡两个属性的场景
  3. 过渡取消时事件的变化
  4. 事件冒泡带来的便利和陷阱
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑