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

React中transitionend事件绑定的函数为何重复执行两次及解决方案

transitionend 事件重复触发的根本成因
  • 核心机制层面:transitionend事件的触发粒度为单个完成过渡的CSS属性,而非元素的整轮过渡动画。只要元素配置的transition规则中存在多个属性同时参与动画,每一个属性过渡完成时都会独立触发一次事件。
  • 折叠组件的常见设计误区:大部分实现可折叠区块的代码会同时为height、opacity、纵向内边距配置同节奏的过渡效果,这类配置天然会触发多次transitionend,哪怕开发者主观上只关注高度属性的变化,其他属性的过渡完成依然会被监听器捕获。
  • 隐性触发场景:如果组件使用了box-sizing: border-box、自动高度计算的逻辑,布局偏移带来的隐式属性变化(如内容溢出导致的滚动条出现、边距的隐式过渡)也会触发额外的事件回调。
单次获取实际高度的解决方案
  • 事件属性校验过滤:在settingHeightForTransition回调内通过事件对象的propertyName字段判断触发来源,仅当属性名匹配目标监听项(如height、max-height)时才执行高度取值逻辑,其他属性触发的事件直接拦截不处理,示例代码如下:
    const settingHeightForTransition = (e) => {
      if (e.propertyName !== 'height') return;
      // 执行divRef绑定DOM的高度读取逻辑
    }
    
  • 执行锁标记兜底:通过React的useRef存储一次性执行标记,回调首次执行完成后置为锁定状态,后续所有触发的事件直接返回;每一轮新的折叠/展开过渡开始前,再将标记重置为可执行状态,完全避免重复执行业务逻辑。
  • 精简过渡配置:从源头上缩小transition规则覆盖的属性范围,仅保留需要做动画的高度相关属性,移除无关属性的过渡配置,从根本上减少事件触发次数,适合结构简单的折叠组件场景。
  • 生命周期清理:在组件卸载阶段主动移除DOM节点上绑定的transitionend监听器,避免残留的旧监听器捕获后续动画事件,引发和重复触发类似的异常表现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 03:06:03