CSS过渡回调

Posted

技术标签:

【中文标题】CSS过渡回调【英文标题】:Callback on CSS transition 【发布时间】:2011-01-06 10:45:09 【问题描述】:

是否可以在 CSS 转换完成时收到通知(如回调)?

【问题讨论】:

***.com/questions/5023514/… 【参考方案1】:

是的,如果浏览器支持这样的事情,那么当转换完成时会触发一个事件。然而,实际事件因浏览器而异:

Webkit 浏览器(Chrome、Safari)使用webkitTransitionEnd Firefox 使用transitionend IE9+ 使用msTransitionEnd Opera 使用oTransitionEnd

但是您应该知道webkitTransitionEnd 并不总是触发!这让我多次感到困惑,如果动画对元素没有影响,似乎就会发生这种情况。为了解决这个问题,在未按预期触发的情况下使用超时来触发事件处理程序是有意义的。有关此问题的博客文章可在此处找到:http://www.cuppadev.co.uk/the-trouble-with-css-transitions/

考虑到这一点,我倾向于在一段看起来有点像这样的代码中使用这个事件:

var transitionEndEventName = "XXX"; //figure out, e.g. "webkitTransitionEnd".. 
var elemToAnimate = ... //the thing you want to animate..
var done = false;
var transitionEnded = function()
     done = true;
     //do your transition finished stuff..
     elemToAnimate.removeEventListener(transitionEndEventName,
                                        transitionEnded, false);
;
elemToAnimate.addEventListener(transitionEndEventName,
                                transitionEnded, false);

//animation triggering code here..

//ensure tidy up if event doesn't fire..
setTimeout(function()
    if(!done)
        console.log("timeout needed to call transition ended..");
        transitionEnded();
    
, XXX); //note: XXX should be the time required for the
        //animation to complete plus a grace period (e.g. 10ms) 

注意:要获取转换事件结束名称,您可以使用以下方法作为答案发布: How do I normalize CSS3 Transition functions across browsers?.

注意:这个问题也与: - CSS3 transition events

【讨论】:

这是一个比接受的答案更完整的答案。为什么这没有得到更多的支持。 记得在transitionEnded中调用transitionEndedHandler(或在addEventListenerremoveEventListener中将transitionEnded更改为transitionEndedHandler并在transitionEndedHandler中调用transitionEnded 谢谢@Miquel;当我的意思是transitionEndedHandler时,我想我只是使用了transitionEnded 我相信 Chromium 问题可以在这里找到:code.google.com/p/chromium/issues/detail?id=388082 虽然,最后一条评论似乎(在我看来是错误的)将其视为一个错误,因此它目前被标记为“赢了“不修复”。 现在不需要不同的名字caniuse.com/#feat=css-transitions【参考方案2】:

我知道 Safari 实现了一个 webkitTransitionEnd 回调,您可以将其直接附加到带有过渡的元素。

他们的例子(重新格式化为多行):

box.addEventListener( 
     'webkitTransitionEnd', 
     function( event )  
         alert( "Finished transition!" ); 
     , false );

【讨论】:

其他浏览器和webkit一样吗? 是的,Mozilla 的“transitionend”和 Opera 的“oTransitionEnd”。 最后的false是做什么的? @meo 与回调中的this 元素有关。但它是一个必需的参数,所以在这种情况下它只是满足要求。 @DougNeiner 最后的假是useCaptureMode。当一个事件发生时,有两个阶段——第一个阶段是捕获模式,第二个阶段是冒泡模式。在捕获模式下,事件从 body 元素下降到指定元素。然后它进入气泡模式,并在其中执行相反的操作。最后的 false 参数指定您希望事件侦听器以冒泡模式发生。这样做的一种用途是在冒泡模式下需要事件处理程序之前附加它们。 =) 37signals.com/svn/posts/…【参考方案3】:

我正在使用下面的代码,比尝试检测浏览器使用哪个特定的结束事件要简单得多。

$(".myClass").one('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', 
function() 
 //do something
);

或者,如果你使用引导程序,那么你可以简单地做

$(".myClass").one($.support.transition.end,
function() 
 //do something
);

这是因为它们在 bootstrap.js 中包含以下内容

+function ($) 
  'use strict';

  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
  // ============================================================

  function transitionEnd() 
    var el = document.createElement('bootstrap')

    var transEndEventNames = 
      'WebkitTransition' : 'webkitTransitionEnd',
      'MozTransition'    : 'transitionend',
      'OTransition'      : 'oTransitionEnd otransitionend',
      'transition'       : 'transitionend'
    

    for (var name in transEndEventNames) 
      if (el.style[name] !== undefined) 
        return  end: transEndEventNames[name] 
      
    

    return false // explicit for ie8 (  ._.)
  

  // http://blog.alexmaccaw.com/css-transitions
  $.fn.emulateTransitionEnd = function (duration) 
    var called = false, $el = this
    $(this).one($.support.transition.end, function ()  called = true )
    var callback = function ()  if (!called) $($el).trigger($.support.transition.end) 
    setTimeout(callback, duration)
    return this
  

  $(function () 
    $.support.transition = transitionEnd()
  )

(jQuery);

【讨论】:

这比较慢,因为它必须在每次事件发生时搜索整个列表以查看它是否是正确的。 @phreakhead 这些方法的性能都将非常相似【参考方案4】:

这可以通过transitionend 事件轻松实现,请参阅文档here 一个简单的例子:

document.getElementById("button").addEventListener("transitionend", myEndFunction);

function myEndFunction() 
	this.innerhtml = "Transition event ended";
#button transition: top 2s; position: relative; top: 0;
<button id="button" onclick="this.style.top = '55px';">Click me to start animation</button>

【讨论】:

这是当今的正确答案,不再需要前缀。 caniuse.com/#feat=css-transitions【参考方案5】:

jQuery.transit plugin,一个用于 CSS3 转换和过渡的插件,可以从脚本调用你的 CSS 动画并给你一个回调。

【讨论】:

以上是关于CSS过渡回调的主要内容,如果未能解决你的问题,请参考以下文章

移动端动画小结

transitionend的运用案例

transitionend的运用案例

d3.js 过渡结束事件

创建人工回调函数以在 Jquery 中启用对 .addclass 和 .css 的回调?

CSS3 动画完成时是不是有回调?