元素是否触发了任何事件以检查css3过渡是否已开始或结束?

#1 楼

W3C CSS过渡草案


CSS过渡的完成将生成相应的DOM事件。将为每个经历过渡的属性触发一个事件。这使内容开发人员可以执行与过渡完成同步的操作。


Webkit



确定何时过渡完成后,为过渡结束时发送的DOM事件设置JavaScript事件侦听器功能。该事件是WebKitTransitionEvent的一个实例,其类型为webkitTransitionEnd


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


Mozilla


转换完成时触发的单个事件。在Firefox中,事件是transitionend,在Opera中是oTransitionEnd,而在WebKit中是webkitTransitionEnd。转换事件
可用。 oTransitionEnd事件
发生在
过渡完成时。


Internet Explorer


transitionend事件发生在过渡完成。如果在完成之前删除过渡,则不会触发该事件。



堆栈溢出:如何跨浏览器规范CSS3过渡功能?

评论


请注意,该事件在firefox中称为“ transitionend”,在Opera中称为“ oTransitionEnd”

– AndreasKöberle
2010年5月13日在20:25

没有人提到这个问题的过渡开始部分。在过渡开始之前,是否没有办法注册要触发的事件处理程序?

– tyler
11年8月31日在17:07

现在有实现这一目标的标准方法吗?似乎2年是很长的时间!事情可能已经改变。

–轻度绒毛
2012年5月22日15:52

@tyler我不知道如何解决缺乏过渡的问题。

–达沃·卢西奇(Davor Lucic)
2012年5月22日下午16:43

@Mild Fuzz链接stackoverflow问题有一个有趣的解决方案。

–达沃·卢西奇(Davor Lucic)
2012年5月22日下午16:43

#2 楼

更新

所有现代浏览器现在都支持以下事件:

element.addEventListener('transitionend', callback, false);

https://caniuse.com/#feat=css-transitions


我正在使用Pete给出的方法,但是现在我开始使用以下

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


  $(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
  }



请注意,有时此事件不会通常不会在属性不变或未触发绘制的情况下触发
。为了确保我们总是得到回调,让我们设置一个超时来手动触发事件。



http://blog.alexmaccaw.com/ css-transitions

评论


你不能那样做。在某些情况下,callbaack将被解雇多次。

–塞巴斯蒂安
2013年6月7日13:57

在同时保留前缀和常规事件名称的浏览器中。您可以使用.one而不是.on来解决此问题

– AlexG
13年7月26日在23:14

顺便说一句:第一个解决方案看起来很方便,但是会导致内存泄漏:codepen.io/jjd/pen/ZEpGGqG为避免这种情况,请对所有事件名称进行命名空间并显式注销它们。否则,每次执行代码时,最终都会添加一堆事件侦听器,而这些侦听器永远不会被清除。 $(“。myClass”)。one('transitionend.namespace webkitTransitionEnd.namespace oTransitionEnd.namespace otransitionend.namespace MSTransitionEnd.namespace',function(){$(this).off('。namespace'); //做某事} );

–杰西
11月30日13:53

#3 楼

现在,所有现代浏览器都支持以下事件:

element.addEventListener('transitionend', callback, false);

可在最新版本的Chrome,Firefox和Safari中运行。甚至是IE10 +。

#4 楼

在Opera 12中,当您使用纯JavaScript进行绑定时,可以使用“ oTransitionEnd”:

document.addEventListener("oTransitionEnd", function(){
    alert("Transition Ended");
});

/>
$(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/

#5 楼

只是为了好玩,不要这样做!

$.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');
});


#6 楼

如果您只想只检测一个转换端,而不使用任何JS框架,则可以使用以下实用工具:

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();


也适用于其他事件:)