Зворотний виклик під час переходу CSS


Відповіді:


82

Я знаю, що Safari реалізує зворотний виклик webkitTransitionEnd, який можна приєднати безпосередньо до елемента з переходом.

Їх приклад (переформатований на кілька рядків):

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

чи є те саме для іншого браузера, ніж веб-браузер?
мей

6
так, "tranitionend" для Mozilla & "oTransitionEnd" в Opera.
qqryq

2
що робить помилкове в кінці?
meo

@meo Це має щось спільне з thisелементом всередині зворотного дзвінка. Але це необхідний параметр, тому в цьому випадку його просто виконання вимоги.
Дуг Нейнер

8
@DougNeiner У кінці помилки призначено для useCaptureMode. Коли відбувається подія, існують дві фази - перша фаза - це режим зйомки, друга - режим міхура. У режимі захоплення подія опускається від елемента тіла до вказаного елемента. Потім він переходить в режим бульбашок, де робить зворотний. Цей заключний помилковий парам вказує, що ви хочете, щоб слухач події відбувався в режимі міхура. Одним із способів цього є приєднання обробників подій безпосередньо до того, як вони знадобляться в бульбашковому режимі. =) 37signals.com/svn/posts/…
rybosome

103

Так, якщо такі речі підтримуються браузером, тоді подія запускається, коли перехід завершується. Фактична подія, однак, відрізняється між браузерами:

  • Використовуються браузери Webkit (Chrome, Safari) webkitTransitionEnd
  • Firefox використовує transitionend
  • IE9 + використовує msTransitionEnd
  • Опера використовує oTransitionEnd

Однак ви повинні знати, що webkitTransitionEndне завжди вистрілює! Це не раз виловлювало мене і, здається, виникає, якщо анімація не вплине на елемент. Щоб обійти це, має сенс використати тайм-аут, щоб запустити обробник подій у випадку, якщо він не спрацьовував так, як очікувалося. Повідомлення в блозі про цю проблему доступне тут: http://www.cuppadev.co.uk/the-trouble-with-css-transitions/ <- 500 Внутрішня помилка сервера

Маючи це на увазі, я схильний використовувати цю подію в шматку коду, який виглядає приблизно так:

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
Це набагато повніша відповідь, ніж прийнята. Чому це не прихильне.
Уес

Чи не забудьте зателефонувати transitionEndedHandlerв transitionEnded(або зміни transitionEndedна transitionEndedHandlerв addEventListenerі removeEventListenerй виклик transitionEndedв transitionEndedHandler)
Мікель

Дякую @Miquel; думаю , що я просто використав , transitionEndedколи я мав в виду transitionEndedHandler.
Марк Родос

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

В даний час немає необхідності в різних іменах 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.