如何在 jQuery 中使用 transitionend?

Posted

技术标签:

【中文标题】如何在 jQuery 中使用 transitionend?【英文标题】:How do I use transitionend in jQuery? 【发布时间】:2011-10-31 08:46:26 【问题描述】:

我需要在允许函数再次重复之前检测 CSS 转换是否完成,以防止弄乱边距。

那么我怎么会有类似的东西

if (transitionend == true) 
  // do stuff
 else 
  // do nothing

【问题讨论】:

【参考方案1】:

我认为这个link 可能对你有帮助。

转换完成时会触发一个事件。在 Firefox,事件为transitionend,在Opera,OTransitionEnd,在 WebKit 它是 webkitTransitionEnd。

el.addEventListener("transitionend", updateTransition, true);

【讨论】:

谢谢,但我以前看过那个文档,但无法理解它。我对 javascript 很陌生,所以添加事件侦听器和所有这些对我来说都没有任何意义。我自己想出了一种方法,但我对你的努力表示赞赏:) 也发布了我的答案。【参考方案2】:

下面的代码将触发 $element 变量中任何元素的 transitionend 事件。有四种不同的事件名称,因为我相信它们涵盖了所有跨浏览器的不一致。将“//您的事件处理程序”注释替换为您希望在触发事件时运行的任何代码。

$element.on('transitionend webkitTransitionEnd oTransitionEnd', function () 
    // your event handler
);

【讨论】:

您能否添加解释以支持您的回答 这是此线程中的最佳答案,因为最初的人要求 jQuery。我很难过人们抱怨“添加解释”代码本身是不言自明的(假设您最初只是粘贴代码) otransitionend 重复。其中之一应该是 mstransitionend 以支持 IE。 使用$element.one而不是$element.on来防止多次执行 您现在唯一需要收听的事件是标准的transitionend:Chrome 36+、WebKit 7.0.6+ 和 Opera 12.10+ 支持它。 IE still suffers a host of problems but you don't need the ms- prefix.【参考方案3】:

使用jQuery data 将有状态数据附加到元素。使用布尔值“阻止”事件发生,并在 transitionend 完成后翻转布尔变量。使用 xram 的代码同时连接所有跨浏览器的 transitionend 事件。

所以对于你的例子......

    onclick 设置 this.data('transitioning', true) transitionend 触发时,设置 this.data('transitioning', false) 如果 this.data('transitioning') == true 则不执行动画。这会在您的点击事件中捕获并检查。

【讨论】:

这真的很有用,因为xram的代码可能会运行多次 @Hengjie 我不这么认为,浏览器要么支持不带前缀的版本,要么支持带前缀的版本。从不支持两者。 刚刚在谷歌浏览器中测试并得到了transitionend,然后是webkitTransitionEnd。我无法弄清楚为什么我的结束转换代码会触发两次,直到我为 event.type 设置警报并看到它为这两个事件触发。【参考方案4】:

您可以创建一个方法,该方法将记住上次调用过渡结束时的时间,因此只触发一次回调。

function transitionEndsOnce($dom, callback) 
  var tick = Date.now();
  $dom.on('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', function(e) 
    var diff = Date.now() - tick;
    tick = Date.now();
    if (diff > 20)  // this number can be changed, but normally all the event trigger are done in the same time
      return callback && callback(e);
    
  );

然后就这样简单地使用它

transitionEndsOnce($('...'), function(e)
  console.log('transition ends once');
);

【讨论】:

你不应该使用off取消订阅活动吗? 如果你希望它只在你需要的时候被调用,因为你建议使用 off,但在这种情况下你可以使用 jQuery.one,它也是这样做的。这里的想法是在一个回调中合并所有属性的所有转换结束,也许方法名称应该更改? 这是错误的!跑一次是什么意思? “在动画后产生相同事件的一堆节点之间运行一次”或“在元素的生命周期内运行一次”?无论哪种情况,此代码都会失败...【参考方案5】:

我注意到类似的问题,例如 “我如何捕捉 touchend 事件?”“mouseup 事件?” 等。

这些观点都是相似的

    复数:即使我们期望被单个事件触发,处理程序也会被触发多次

    depth:事件在我们的处理程序捕获它们之前在树中更深地冒泡。

例子:

    touchstart 后面可以跟 mousedown,在同时具有鼠标和触摸屏的设备中,反之亦然,

    touchend 后面可以跟 mouseup,原因类似,

    a animationstart 之后可以跟随许多其他类似的事件,具体取决于您编写 css 的方式,

    由于上述原因,animationend 之后也可能出现许多类似的事件。

如果我们需要针对一组类似事件触发我们的处理程序一次,即由单个动作产生的事件,例如按下某物的人。我们需要引入 事件锁 并使用 2 个处理程序,一个在事件开始时使用,一个在事件结束时使用处理程序 即使我们不需要或不想要附带事件的处理程序。

可以是树中更高父节点的属性。

对于臭名昭著的事件夫妇:animationstart - animationend 这样的功能可以是:

var oneTransition = (function()
   var $parent,
       type,
       callback,
       unlockCallback,
       newCallback,
       start = 'webkitTransitionStart otransitionstart oTransitionStart msTransitionStart transitionstart',
       end = 'webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend';

   unlockCallback = function()
      $parent.data('oneTransitionLock', false);
   ;

   newCallback = function(e)
      if($parent.data('oneTransitionLock'))
         return;
      else
         $parent.data('oneTransitionLock', true);

      callback(e);
   ;

   return function()
      var args = Array.prototype.slice.call(arguments, 0);

      $parent = $(args[0]);     // 1st arg
      type = args[1];           // 2nd arg
      callback = args[2];       // 3rd arg

      if((args.length < 3) || ((type != 'start') && (type != 'end')) || (typeof(callback) != 'function'))
         return;

      $parent.off(start).off(end);
      if(type == 'start')
         $parent.data('oneTransitionLock', false);
         $parent.on(start, newCallback);
         $parent.on(end, unlockCallback);
      else if(type == 'end')
         $parent.on(start, unlockCallback);
         $parent.on(end, newCallback);
      
   
)();

你可以这样称呼它:

oneTransition(node, 'start' or 'end', funcion()...);

有趣的是,它可以在动画开始或结束时运行:

    第一个参数。节点引用,

    第二个参数。一个字符串,代表我们的回调和

    的事件

    第三个参数。我们的实际回调。

jsFiddle

【讨论】:

以上是关于如何在 jQuery 中使用 transitionend?的主要内容,如果未能解决你的问题,请参考以下文章

为 CSS/JS/jQuery 动画使用 Velocity.js 或 Transit.js?

Jquery UI Draggable 添加了 CSS 的 Scale Transition 问题

jquery.transit:提供流畅CSS3变换和过渡效果的jQuery插件

用 Transit 中的 transition() 替换 jQuery 幻灯片

使用 CSS 和 jQuery 创建自己的 Vue <transition-group> 动画

jQuery Transit 过渡效果