CSS3遷移イベント


回答:


210

W3C CSS Transitions Draft

CSS移行が完了すると、対応するDOMイベントが生成されます。遷移が発生するプロパティごとにイベントが発生します。これにより、コンテンツ開発者は、遷移の完了と同期するアクションを実行できます。


Webkit

トランジションがいつ完了するかを判断するには、トランジションの最後に送信されるDOMイベントのJavaScriptイベントリスナー関数を設定します。イベントはWebKitTransitionEventのインスタンスであり、そのタイプはwebkitTransitionEndです。

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

Mozilla

遷移が完了すると発生する単一のイベントがあります。Firefoxではイベントはtransitionend、OperaではoTransitionEnd、WebKitではイベントですwebkitTransitionEnd

オペラ

使用できる遷移イベントには1つのタイプがあります。oTransitionEndイベントは、移行の完了時に起こります。

インターネットエクスプローラ

transitionendイベントは、移行の完了時に起こります。完了前にトランジションが削除されると、イベントは発生しません。


スタックオーバーフロー:ブラウザー間でCSS3遷移機能を正規化するにはどうすればよいですか?


3
イベントは、FirefoxとOperaで「oTransitionEnd」の「transitionend」と呼ばれることに注意してください
アンドレアスKöberle

8
質問の移行開始部分については誰も言及していません。遷移が始まる前に発生するイベントハンドラーを登録する方法はありませんか?
タイラー

これを達成する標準的な方法はありますか?2年は長いようです!物事はおそらく変化しました。
軽度のファズ

@tylerトランジション開始の欠如を回避する方法がわかりません。
Davor Lucic

@Mild Fuzzにリンクされたstackoverflowの質問には興味深い解決策があります。
Davor Lucic

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が複数回実行されます。
セバスチャン2013年

11
接頭辞付きのイベント名と通常のイベント名の両方を保持するブラウザ。.onではなく.oneを使用することで回避できます
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');
});

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

他のイベントの使用にも適しています:)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.