有没有任何事件可以被元素触发来检查CSS3过渡是否已经开始或结束?
完成 CSS 过渡后将生成相应的 DOM 事件,每个发生过渡的属性都会触发一个事件。这使得内容开发人员可以执行与过渡完成同步的操作。
要确定过渡何时完成,请为发送到过渡结束时的 DOM 事件设置 JavaScript 事件监听器函数。该事件是 WebKitTransitionEvent 的实例,其类型为
webkitTransitionEnd
。
box.addEventListener( 'webkitTransitionEnd',
function( event ) { alert( "Finished transition!" ); }, false );
在过渡完成时,会触发单个事件。在 Firefox 中,该事件是
transitionend
,在 Opera 中是oTransitionEnd
,而在 WebKit 中则是webkitTransitionEnd
。
有一种类型的过渡事件可用。当过渡完成时,
oTransitionEnd
事件就会触发。
在过渡完成时,会触发
transitionend
事件。如果在过渡完成前移除了过渡,则不会触发此事件。
更新
现代浏览器都支持无前缀事件:
element.addEventListener('transitionend', callback, false);
https://caniuse.com/#feat=css-transitions
我之前一直在使用 Pete 给出的方法,但现在我开始使用以下方法:
$(".myClass").one('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd',
function() {
//do something
});
如果您使用Bootstrap,则可以简单地执行以下操作:
$(".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 ( ._.)
}
$(function () {
$.support.transition = transitionEnd()
})
}(jQuery);
请注意,它们还包括一个emulateTransitionEnd函数,这可能是必要的,以确保始终发生回调。
// 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
}
请注意,有时此事件不会触发,通常是因为属性未更改或未触发绘制。为了确保我们始终获得回调,请设置一个超时,手动触发该事件。
现代浏览器现在支持无需前缀的事件:
element.addEventListener('transitionend', callback, false);
适用于最新版本的Chrome,Firefox和Safari。甚至也支持IE10+。
在Opera 12中,当您使用纯JavaScript进行绑定时,'oTransitionEnd'会起作用:
document.addEventListener("oTransitionEnd", function(){
alert("Transition Ended");
});
然而,如果您使用jQuery绑定事件,您需要使用'otransitionend'。
$(document).bind("otransitionend", function(){
alert("Transition Ended");
});
如果你正在使用Modernizr或bootstrap-transition.js,你可以简单地进行更改:
var transEndEventNames = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd otransitionend',
'msTransition' : 'MSTransitionEnd',
'transition' : 'transitionend'
},
transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
你也可以在这里找到一些信息http://www.ianlunn.co.uk/blog/articles/opera-12-otransitionend-bugs-and-workarounds/
仅仅出于娱乐目的,请勿实践!
$.fn.transitiondone = function () {
return this.each(function () {
var $this = $(this);
setTimeout(function () {
$this.trigger('transitiondone');
}, (parseFloat($this.css('transitionDelay')) + parseFloat($this.css('transitionDuration'))) * 1000);
});
};
$('div').on('mousedown', function (e) {
$(this).addClass('bounce').transitiondone();
});
$('div').on('transitiondone', function () {
$(this).removeClass('bounce');
});
function once = function(object,event,callback){
var handle={};
var eventNames=event.split(" ");
var cbWrapper=function(){
eventNames.forEach(function(e){
object.removeEventListener(e,cbWrapper, false );
});
callback.apply(this,arguments);
};
eventNames.forEach(function(e){
object.addEventListener(e,cbWrapper,false);
});
handle.cancel=function(){
eventNames.forEach(function(e){
object.removeEventListener(e,cbWrapper, false );
});
};
return handle;
};
使用方法:
var handler = once(document.querySelector('#myElement'), 'transitionend', function(){
//do something
});
handler.cancel();
这也适用于其他事件使用情况:)