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


Ответы:


82

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

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

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

есть ли то же самое для другого браузера, кроме webkit?
meo

6
да, «transitionend» для Mozilla и «oTransitionEnd» в Opera.
qqryq 01

2
что делает ложное в конце?
meo

@meo Это как-то связано с thisэлементом внутри обратного вызова. Но это обязательный параметр, поэтому в данном случае он просто выполняет требование.
Дуг Найнер

8
@DougNeiner Ложь в конце предназначена для useCaptureMode. Когда происходит событие, есть две фазы: первая фаза - режим захвата, вторая - пузырьковый режим. В режиме захвата событие спускается от основного элемента к указанному элементу. Затем он переходит в режим пузырьков, где происходит обратное. Этот последний параметр false указывает, что вы хотите, чтобы прослушиватель событий работал в пузырьковом режиме. Одно из применений этого - присоединение обработчиков событий непосредственно перед тем, как они понадобятся в пузырьковом режиме. =) 37signals.com/svn/posts/…
rybosome

103

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

  • Браузеры Webkit (Chrome, Safari) используют webkitTransitionEnd
  • Firefox использует transitionend
  • IE9 + использует msTransitionEnd
  • Opera использует 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


2
Это гораздо более полный ответ, чем принятый. Почему это не получает больше голосов.
Wes

Не забудьте позвонить transitionEndedHandlerв transitionEnded(или изменения transitionEndedна transitionEndedHandlerв addEventListenerи removeEventListenerи вызов transitionEndedв transitionEndedHandler)
Микель

Спасибо @Miquel; думаю, я просто использовал, transitionEndedкогда имел в виду transitionEndedHandler.
Марк Роудс

Я считаю, что проблему Chromium для этого можно найти здесь: code.google.com/p/chromium/issues/detail?id=388082 Хотя последний комментарий, кажется (неправильно на мой взгляд) обесценивает его как ошибку и, следовательно, в настоящее время помечено как "не будет исправлено".
Willster

В настоящее время нет необходимости в разных именах caniuse.com/#feat=css-transitions
Хуан Мендес,

43

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

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

2
Это медленнее, потому что он должен перебирать весь этот список каждый раз, когда происходит событие, чтобы увидеть, правильное ли оно.
phreakhead

3
@phreakhead Производительность любого из этих подходов будет очень похожей
Том


5

Этого легко добиться с помощью 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>


1
Сегодня это правильный ответ, префиксы больше не нужны. caniuse.com/#feat=css-transitions
Хуан Мендес,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.