CSS过渡上的回调


Answers:


82

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

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

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

除Webkit之外,其他浏览器也有相同的东西吗?
meo

6
是的,Mozilla中的“ transitionend”和Opera中的“ oTransitionEnd”。
qqryq 2011年

2
最后的错误是做什么的?
MEO

@meo它与this回调中的元素有关。但是它是必需的参数,因此在这种情况下,它仅满足要求。
Doug Neiner 2011年

8
@DougNeiner结尾的错误是for useCaptureMode。当事件发生时,有两个阶段-第一阶段是捕获模式,第二阶段是冒泡模式。在捕获模式下,事件从body元素下降到指定元素。然后进入气泡模式,然后相反。最后一个false参数指定您希望事件监听器以气泡模式发生。一种用法是在气泡模式下将事件处理程序附加到事件处理程序之前。=)37signals.com/svn/posts/...
rybosome

103

是的,如果浏览器支持这些功能,则转换完成时将触发一个事件。但是,实际事件在浏览器之间有所不同:

  • Webkit浏览器(Chrome,Safari)使用 webkitTransitionEnd
  • Firefox使用 transitionend
  • IE9 +的用途 msTransitionEnd
  • 歌剧用途 oTransitionEnd

但是,您应该意识到,webkitTransitionEnd并不总是会触发!这吸引了我很多次,如果动画对元素没有影响,似乎会发生这种情况。为了解决这个问题,在未按预期方式触发事件处理程序的情况下,可以使用超时来触发事件处理程序。有关此问题的博客文章,请访问:http : //www.cuppadev.co.uk/the-trouble-with-css-transitions/ <-500 Internal Server Error

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

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) 

注意:要获取转换事件的最终名称,您可以使用以下方法作为答案发布的方法: 如何在浏览器之间规范CSS3转换功能?

注意:此问题还与以下内容有关:-CSS3过渡事件


2
这是一个比已接受的答案更全面的答案。为什么这不是更好的选择。
2013年

记得拨打transitionEndedHandlertransitionEnded(或改变transitionEndedtransitionEndedHandleraddEventListenerremoveEventListener和呼叫transitionEndedtransitionEndedHandler
米克尔

谢谢@Miquel; 我想我只是在用transitionEnded我的意思 transitionEndedHandler
Mark Rhodes

我认为可以在以下位置找到Chromium的问题:code.google.com/p/chromium/issues/detail?id=388082虽然,最后的评论(我认为不正确)似乎将其打为错误,因此,当前标记为“无法修复”。
Willster,2015年

如今,无需使用其他名称caniuse.com/#feat=css-transitions
Juan Mendes

43

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

$(".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);

2
这比较慢,因为每次事件发生时它都必须搜索整个列表,以查看它是否正确。
phreakhead 2014年

3
@phreakhead这些方法中的任何一种的性能都将非常相似
汤姆(Tom)


5

这可以通过transitionendEvent 轻松实现,请参见此处 的文档一个简单的示例:

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>


1
如今,这是正确的答案,不再需要前缀。caniuse.com/#feat=css-transitions
Juan Mendes
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.