События перехода CSS3

Есть ли какие-либо события, запускаемые элементом, чтобы проверить, начался или закончился переход css3?


person Andreas Köberle    schedule 08.05.2010    source источник


Ответы (6)


Черновик переходов W3C CSS

Завершение перехода CSS генерирует соответствующее событие DOM. Событие запускается для каждого свойства, которое подвергается переходу. Это позволяет разработчику содержимого выполнять действия, которые синхронизируются с завершением перехода.


Webkit

Чтобы определить, когда переход завершится, установите функцию прослушивания событий JavaScript для события DOM, которое отправляется в конце перехода. Событие является экземпляром WebKitTransitionEvent и имеет тип webkitTransitionEnd.

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

Mozilla

Существует одно событие, которое запускается при завершении переходов. В Firefox это событие transitionend, в Opera — oTransitionEnd, а в WebKit — webkitTransitionEnd.

Opera

Доступен один тип события перехода. Событие oTransitionEnd происходит при завершении перехода.

Internet Explorer

Событие transitionend происходит при завершении перехода. Если переход будет удален до завершения, событие не сработает.


Переполнение стека: как нормализовать функции перехода CSS3 в разных браузерах?< /а>

person Davor Lucic    schedule 08.05.2010

Обновить

Все современные браузеры теперь поддерживают событие без префикса:

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

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


Я использовал подход, предложенный Питом, однако теперь я начал использовать следующие

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

person Tom    schedule 13.12.2012
comment
Вы не можете сделать что-то подобное. В некоторых случаях обратный вызов будет запущен более одного раза. - person sebastian; 07.06.2013
comment
В браузерах, которые сохраняют как префиксные, так и обычные имена событий. Вы можете обойти это, используя .one вместо .on - person AlexG; 27.07.2013
comment
К вашему сведению: первое решение выглядит красиво и удобно, но вызывает утечку памяти: codepen.io/jjd/pen /ZEpGGqG Чтобы избежать этого, создайте пространство имен для всех имен событий и явно отмените их регистрацию. В противном случае вы в конечном итоге добавите кучу прослушивателей событий каждый раз, когда код выполняется, и они никогда не очищаются. $(.myClass).one('transitionend.namespace webkitTransitionEnd.namespace oTransitionEnd.namespace otransitionend.namespace MSTransitionEnd.namespace', function() { $(this).off('.namespace'); // сделать что-нибудь }); - person Jesse; 30.11.2020

Все современные браузеры теперь поддерживают событие без префикса:

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

Работает в последних версиях Chrome, Firefox и Safari. Даже IE10+.

person neave    schedule 18.12.2013

В 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/

person Peter    schedule 29.08.2012

Просто для удовольствия, не делайте этого!

$.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');
});
person yckart    schedule 25.01.2013

Если вы просто хотите обнаружить только один конец перехода, не используя какой-либо 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();

Это хорошо и для других случаев использования событий :)

person OpherV    schedule 06.11.2016