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

如何阻止transitionend事件多次触发?已尝试one()等方法无效

这个问题我之前也碰到过!过渡事件触发多次通常有两个原因:一是浏览器对过渡事件的前缀实现(比如webkitTransitionEnd和transitionend会同时触发),二是元素有多个过渡属性(比如同时过渡宽、高、背景色,每个属性结束都会触发一次事件)。再加上你需要区分「添加类的过渡」和「移除类的过渡」,得结合标记位和事件去重来解决。

给你一套可行的方案,一步步来:

1. 统一过渡事件监听,处理兼容性

首先封装一个兼容所有浏览器的过渡结束事件监听方法,同时避免同一过渡的重复触发:

function onTransitionEnd($element, callback) {
  let triggered = false;
  const endEvents = ['transitionend', 'webkitTransitionEnd', 'oTransitionEnd', 'MSTransitionEnd'];
  
  function handleEnd(event) {
    // 确保只执行一次回调,避免多属性/多前缀重复触发
    if (!triggered) {
      triggered = true;
      // 移除所有事件监听
      endEvents.forEach(evt => $element.off(evt, handleEnd));
      callback(event);
    }
  }
  
  endEvents.forEach(evt => $element.on(evt, handleEnd));
}

2. 结合临时标记区分「添加类的过渡」

在点击添加类时,给元素加一个自定义属性作为标记,只有当这个标记存在时,我们才处理过渡结束事件;执行完逻辑后移除标记,这样后续移除类的过渡就不会触发回调了:

$(document).ready(function() {
  $(document).on("click", ".main", function() {
    const $this = $(this);
    // 添加类之前先标记这是我们要监听的过渡
    $this.attr('data-waiting-transition', 'true');
    $this.addClass('example');
    
    // 监听过渡结束
    onTransitionEnd($this, function() {
      // 这里写你需要执行的逻辑,比如:
      console.log('过渡结束啦!只触发一次');
      
      // 移除标记,后续移除类的过渡不会触发
      $this.removeAttr('data-waiting-transition');
    });
  });
  
  // 如果你有移除类的逻辑,比如另一个点击事件
  $(document).on("click", ".remove-class", function() {
    $('.main').removeClass('example');
    // 这里不需要监听过渡结束,因为标记已经被移除了
  });
});

为什么之前的方法没用?

  • one():如果是直接绑定到元素上,它确实只会触发一次,但如果你的元素有多个过渡属性或者浏览器触发了多个前缀事件,one()会针对每个事件各触发一次,所以还是会多次执行。我们上面的封装里用了triggered标志位,确保不管多少个事件触发,回调只执行一次。
  • stopPropagation()/return false:过渡事件是元素自身的事件,不会冒泡到父元素(或者说冒泡不影响多次触发的问题),所以这两个方法对多触发的问题没用。

额外优化:如果需要监听移除类的过渡怎么办?

如果之后你需要区分添加和移除的过渡,可以把标记改成不同的值,比如添加类时设data-transition-type="add",移除时设data-transition-type="remove",然后在回调里判断这个值来执行不同逻辑。

这样就能完美解决你的问题啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:19:39