CSS3 过渡事件

IT技术 javascript css events css-transitions
2021-02-01 01:32:02

元素是否会触发任何事件来检查 css3 转换是否已开始或结束?

6个回答

W3C CSS 过渡草案

CSS Transition 的完成会生成相应的 DOM 事件。每个经历转换的属性都会触发一个事件。这允许内容开发者执行与转换完成同步的操作。


网络套件

要确定转换何时完成,请为转换结束时发送的 DOM 事件设置 JavaScript 事件侦听器函数。该事件是 WebKitTransitionEvent 的一个实例,其类型为webkitTransitionEnd

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

Mozilla

转换完成时会触发一个事件。在 Firefox 中,事件为transitionend,在 Opera 中为oTransitionEnd,而在 WebKit 中为webkitTransitionEnd

歌剧

有一种类型的转换事件可用。oTransitionEnd事件在转换完成时发生。

IE浏览器

transitionend事件在转换完成时发生。如果在完成之前移除转换,则不会触发该事件。


Stack Overflow:如何规范跨浏览器的 CSS3 过渡功能?

没有人提到问题的过渡开始部分。有没有办法在转换开始之前注册要触发的事件处理程序?
2021-03-13 01:32:02
@tyler 我不知道如何解决缺少过渡开始的问题。
2021-03-15 01:32:02
@Mild Fuzz 链接的 stackoverflow 问题有有趣的解决方案。
2021-03-18 01:32:02
现在有实现这一目标的标准方法吗?看来2年很长了!事情可能已经发生了变化。
2021-03-23 01:32:02
请注意,该事件在 Firefox 中称为“transitionend”,在 Opera 中称为“oTransitionEnd”
2021-04-07 01:32:02

更新

所有现代浏览器现在都支持无前缀事件:

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

仅供参考:第一个解决方案看起来不错且方便,但它会导致内存泄漏: codepen.io/jjd/pen/ZEpGGqG 为避免这种情况,命名所有事件名称并明确取消注册它们。否则,您最终会添加一堆事件侦听器,每次执行代码时都不会清除它们。$(".myClass").one('transitionend.namespace webkitTransitionEnd.namespace oTransitionEnd.namespace otransitionend.namespace MSTransitionEnd.namespace', function() { $(this).off('.namespace'); //做某事 } );
2021-03-18 01:32:02
你不能做那样的事情。在某些情况下,回调会被触发不止一次。
2021-04-06 01:32:02
在保留前缀和常规事件名称的浏览器中。您可以通过使用 .one 而不是 .on 来解决它
2021-04-06 01:32:02

所有现代浏览器现在都支持无前缀事件:

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