Обратный вызов при переходе CSS

Можно ли получить уведомление (например, обратный вызов) после завершения перехода CSS?


person Pompair    schedule 18.01.2010    source источник
comment
stackoverflow .com/questions/5023514/   -  person zloctb    schedule 06.03.2015


Ответы (5)


Я знаю, что Safari реализует webkitTransitionEnd обратный вызов, который можно прикрепить непосредственно к элементу с переходом.

Их пример (переформатированный в несколько строк):

box.addEventListener( 
     'webkitTransitionEnd', 
     function( event ) { 
         alert( "Finished transition!" ); 
     }, false );
person Doug Neiner    schedule 18.01.2010
comment
есть ли то же самое для другого браузера, кроме webkit? - person meo; 28.02.2011
comment
да, «transitionend» для Mozilla и «oTransitionEnd» для Opera. - person qqryq; 01.03.2011
comment
что делает false в конце? - person meo; 15.03.2011
comment
@meo Это как-то связано с элементом this внутри обратного вызова. Но это обязательный параметр, поэтому в данном случае он просто выполняет требование. - person Doug Neiner; 19.03.2011
comment
@DougNeiner Ложь в конце предназначена для useCaptureMode. Когда происходит событие, есть две фазы — первая фаза — режим захвата, вторая — пузырьковый режим. В режиме захвата событие спускается от элемента body к указанному элементу. Затем он переходит в пузырьковый режим, где происходит обратное. Этот последний ложный параметр указывает, что вы хотите, чтобы прослушиватель событий происходил в пузырьковом режиме. Одним из способов использования этого является присоединение обработчиков событий прямо перед тем, как они потребуются в пузырьковом режиме. =) 37signals.com/ SVN/сообщения/ - person rybosome; 29.07.2012
comment
Я считаю, что это всего лишь обязательный параметр в Firefox. - person danwellman; 24.02.2015

Да, если такие вещи поддерживаются браузером, то при завершении перехода срабатывает событие. Однако фактическое событие отличается в разных браузерах:

  • Браузеры Webkit (Chrome, Safari) используют webkitTransitionEnd
  • Firefox использует transitionend
  • IE9+ использует msTransitionEnd
  • Опера использует oTransitionEnd

Однако вы должны знать, что webkitTransitionEnd не всегда срабатывает! Это ловило меня несколько раз и, кажется, происходит, если анимация не влияет на элемент. Чтобы обойти это, имеет смысл использовать тайм-аут для запуска обработчика события в случае, если он не был запущен должным образом. Сообщение в блоге об этой проблеме доступно здесь: http://www.cuppadev.co.uk/the-trouble-with-css-transitions/ ‹-- 500 Internal Server Error

Имея это в виду, я обычно использую это событие в фрагменте кода, который выглядит примерно так:

var transitionEndEventName = "XXX"; //figure out, e.g. "webkitTransitionEnd".. 
var elemToAnimate = ... //the thing you want to animate..
var done = false;
var transitionEnded = function(){
     done = true;
     //do your transition finished stuff..
     elemToAnimate.removeEventListener(transitionEndEventName,
                                        transitionEnded, false);
};
elemToAnimate.addEventListener(transitionEndEventName,
                                transitionEnded, false);

//animation triggering code here..

//ensure tidy up if event doesn't fire..
setTimeout(function(){
    if(!done){
        console.log("timeout needed to call transition ended..");
        transitionEnded();
    }
}, XXX); //note: XXX should be the time required for the
        //animation to complete plus a grace period (e.g. 10ms) 

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

Примечание: этот вопрос также связан с: - событиями перехода CSS3

person Mark Rhodes    schedule 05.07.2012
comment
Это гораздо более полный ответ, чем принятый. Почему за это больше не проголосовали. - person Wes; 23.06.2013
comment
Не забудьте вызвать transitionEndedHandler в transitionEnded (или заменить transitionEnded на transitionEndedHandler в addEventListener и removeEventListener и вызвать transitionEnded в transitionEndedHandler) - person Miquel; 31.01.2015
comment
Спасибо @Miquel; думаю, я только что использовал transitionEnded, когда имел в виду transitionEndedHandler. - person Mark Rhodes; 31.01.2015
comment
Я полагаю, что проблему Chromium для этого можно найти здесь: code.google. com/p/chromium/issues/detail?id=388082 Хотя последний комментарий, кажется (на мой взгляд, неправильно) игнорирует его как ошибку, и поэтому в настоящее время он помечен как не исправимый. - person Willster; 11.06.2015
comment
В настоящее время нет необходимости в разных именах caniuse.com/#feat=css-transitions - person Juan Mendes; 21.02.2020

Я использую следующий код, это намного проще, чем пытаться определить, какое конкретное конечное событие использует браузер.

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

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

  $(function () {
    $.support.transition = transitionEnd()
  })

}(jQuery);
person Tom    schedule 13.12.2012
comment
Это медленнее, потому что каждый раз, когда происходит событие, ему приходится просматривать весь список, чтобы определить, является ли оно правильным. - person phreakhead; 13.02.2014
comment
@phreakhead Производительность любого из этих подходов будет очень похожа - person Tom; 13.05.2014

подключаемый модуль jQuery.transit, подключаемый модуль для преобразований и переходов CSS3, может вызывать анимацию CSS из сценария и дать вам обратный звонок.

person Brian    schedule 05.07.2012

Этого легко добиться с помощью события transitionend. См. документацию здесь. Простой пример:

document.getElementById("button").addEventListener("transitionend", myEndFunction);

function myEndFunction() {
	this.innerHTML = "Transition event ended";
}
#button {transition: top 2s; position: relative; top: 0;}
<button id="button" onclick="this.style.top = '55px';">Click me to start animation</button>

person Yehuda Schwartz    schedule 16.11.2018
comment
В настоящее время это правильный ответ, больше не нужны префиксы. caniuse.com/#feat=css-transitions - person Juan Mendes; 21.02.2020