CSS3 переходные события

Ответы:

210

W3C CSS Transitions Draft

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


Webkit

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

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

Mozilla

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

опера

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

Internet Explorer

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


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

Давор Лючич
источник
3
Обратите внимание, что событие называется «transitionend» в Firefox и «oTransitionEnd» в Opera
Andreas Köberle
8
Никто ничего не упомянул о переходной части вопроса. Нет ли способа зарегистрировать обработчик событий для запуска до начала перехода?
Тайлер
Есть ли сейчас стандартный способ достижения этого? Кажется, 2 года это долго! Вещи, вероятно, изменились.
Мягкий пух
@ Tyler Я не знаю, как обойти отсутствие переходов - начало.
Давор Лючич
У @Mild Fuzz связанного вопроса stackoverflow есть интересное решение.
Давор Лючич
73

Обновить

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

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

Том
источник
3
Вы не можете сделать что-то подобное. В некоторых случаях callbaack будет запущен более одного раза.
Себастьян
11
В браузерах, которые содержат как префиксные, так и обычные имена событий. Вы можете обойти это, используя .one вместо .on
AlexG
61

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

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

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

Нив
источник
16

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

Питер
источник
6

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

$.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');
});
yckart
источник
3

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

Это хорошо и для других мероприятий :)

OpherV
источник