CSS3 події переходу


Відповіді:


210

Проект переходів CSS W3C

Завершення переходу CSS генерує відповідну подію DOM. Подія запускається для кожної власності, яка переходить до переходу. Це дозволяє розробнику вмісту виконувати дії, які синхронізуються із завершенням переходу.


Вебкіт

Щоб визначити, коли перехід завершується, встановіть функцію прослуховування подій JavaScript для події DOM, що надсилається в кінці переходу. Подія є екземпляром WebKitTransitionEvent, і його тип є webkitTransitionEnd.

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

Мозіла

Є одна подія, яку запускають, коли переходи завершуються. У Firefox подія є transitionendв Opera oTransitionEnd, та у WebKit webkitTransitionEnd.

Опера

Є один тип події переходу. oTransitionEndПодія відбувається при завершенні переходу.

Internet Explorer

transitionendПодія відбувається при завершенні переходу. Якщо перехід буде видалено до завершення, подія не запуститься.


Переповнення стека: Як нормалізувати функції переходу CSS3 у веб-переглядачах?


3
Зауважимо, що подія називається "transitionend" у firefox та "oTransitionEnd" в Opera
Andreas Köberle

8
Ніхто нічого не згадав про перехідну частину питання. Чи немає способу зареєструвати обробник події, який буде звільнений до початку переходу?
tyler

Чи існує зараз стандартний спосіб цього досягти? Здається, 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
Ви не можете зробити щось подібне. У деяких випадках зворотний виклик буде видалено не один раз.
себастьян

11
У браузерах, які містять як префіксні, так і звичайні назви подій навколо. Ви можете її вирішити, скориставшись .one замість
.on


16

В Opera 12, коли ви зв’язуєтеся за допомогою простого JavaScript, "oTransitionEnd" буде працювати:

document.addEventListener("oTransitionEnd", function(){
    alert("Transition Ended");
});

однак якщо ви пов'язуєте jQuery, вам потрібно використовувати "otransitionend"

$(document).bind("otransitionend", function(){
    alert("Transition Ended");
});

Якщо ви використовуєте Modernizr або bootstrap-translation.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');
});

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();

Це добре і для інших подій :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.