Sự kiện chuyển tiếp CSS3


Câu trả lời:


210

Bản thảo chuyển tiếp CSS của W3C

Việc hoàn thành Chuyển đổi CSS tạo ra một Sự kiện DOM tương ứng. Một sự kiện được thực hiện cho mỗi tài sản trải qua quá trình chuyển đổi. Điều này cho phép nhà phát triển nội dung thực hiện các hành động đồng bộ hóa với việc hoàn thành quá trình chuyển đổi.


Webkit

Để xác định khi quá trình chuyển đổi hoàn thành, hãy đặt chức năng nghe sự kiện JavaScript cho sự kiện DOM được gửi ở cuối quá trình chuyển đổi. Sự kiện này là một ví dụ của WebKitTransitionEvent và loại của nó là webkitTransitionEnd.

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

Mozilla

Có một sự kiện duy nhất được kích hoạt khi quá trình chuyển đổi hoàn thành. Trong Firefox, sự kiện này là transitionendở Opera oTransitionEndvà trên WebKit webkitTransitionEnd.

Opera

Có một loại sự kiện chuyển tiếp có sẵn. Sự oTransitionEndkiện xảy ra khi hoàn thành quá trình chuyển đổi.

trình duyệt web IE

Sự transitionendkiện xảy ra khi hoàn thành quá trình chuyển đổi. Nếu quá trình chuyển đổi bị xóa trước khi hoàn thành, sự kiện sẽ không kích hoạt.


Tràn ngăn xếp: Làm cách nào để bình thường hóa các chức năng Chuyển đổi CSS3 trên các trình duyệt?


3
Lưu ý rằng sự kiện này được gọi là "quá trình chuyển đổi" trong firefox và "oTransitionEnd" trong Opera
Andreas Köberle

8
Không ai đã đề cập bất cứ điều gì về phần bắt đầu chuyển đổi của câu hỏi. Có cách nào để đăng ký một trình xử lý sự kiện sẽ bị sa thải trước khi quá trình chuyển đổi bắt đầu không?
trùm

Bây giờ có một cách tiêu chuẩn để đạt được điều này? Có vẻ 2 năm là một thời gian dài! Mọi thứ có thể đã thay đổi.
Fuzz nhẹ

@tyler Tôi không biết làm thế nào để giải quyết vấn đề thiếu chuyển tiếp - bắt đầu.
Davor Lucic

@Mild Fuzz câu hỏi stackoverflow liên kết có giải pháp thú vị.
Davor Lucic

73

Cập nhật

Tất cả các trình duyệt hiện đại hiện hỗ trợ sự kiện chưa được chuẩn bị:

element.addEventListener('transitionend', callback, false);

https://caniuse.com/#feat=css-transitions


Tôi đã sử dụng cách tiếp cận được đưa ra bởi Pete, tuy nhiên bây giờ tôi đã bắt đầu sử dụng cách sau

$(".myClass").one('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', 
function() {
 //do something
});

Ngoài ra, nếu bạn sử dụng bootstrap thì bạn chỉ cần làm

$(".myClass").one($.support.transition.end,
function() {
 //do something
});

Đây là vì họ bao gồm những điều sau đây trong 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);

Lưu ý rằng chúng cũng bao gồm hàm emulationTransitionEnd có thể cần thiết để đảm bảo gọi lại luôn xảy ra.

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

Xin lưu ý rằng đôi khi sự kiện này không kích hoạt, thường là trong trường hợp khi các thuộc tính không thay đổi hoặc sơn không được kích hoạt. Để đảm bảo chúng tôi luôn nhận được một cuộc gọi lại, hãy đặt thời gian chờ sẽ kích hoạt sự kiện theo cách thủ công.

http://blog.alexmaccaw.com/css-transitions


3
Bạn không thể làm một cái gì đó như thế. Trong một số trường hợp, Callbaack sẽ bị sa thải nhiều lần.
sebastian

11
Trong các trình duyệt giữ cả tiền tố và tên sự kiện thông thường xung quanh. Bạn có thể giải quyết nó bằng cách sử dụng .one thay vì
.on

61

Tất cả các trình duyệt hiện đại hiện hỗ trợ sự kiện chưa được chuẩn bị:

element.addEventListener('transitionend', callback, false);

Hoạt động trong các phiên bản mới nhất của Chrome, Firefox và Safari. Ngay cả IE10 +.


16

Trong Opera 12 khi bạn liên kết bằng JavaScript đơn giản, 'oTransitionEnd' sẽ hoạt động:

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

tuy nhiên nếu bạn liên kết thông qua jQuery, bạn cần sử dụng 'otransitionend'

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

Trong trường hợp bạn đang sử dụng Modernizr hoặc bootstrap-trans.js, bạn chỉ cần thay đổi:

var transEndEventNames = {
    'WebkitTransition' : 'webkitTransitionEnd',
    'MozTransition'    : 'transitionend',
    'OTransition'      : 'oTransitionEnd otransitionend',
    'msTransition'     : 'MSTransitionEnd',
    'transition'       : 'transitionend'
},
transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];

Bạn cũng có thể tìm thấy một số thông tin ở đây http://www.ianlunn.co.uk/blog/articles/opera-12-otransitionend-bugs-and-workaround/


6

Chỉ để cho vui, đừng làm điều này!

$.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

Nếu bạn chỉ muốn phát hiện một kết thúc chuyển đổi duy nhất, mà không sử dụng bất kỳ khung JS nào thì đây là một chức năng tiện ích nhỏ:

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

Sử dụng:

var handler = once(document.querySelector('#myElement'), 'transitionend', function(){
   //do something
});

sau đó nếu bạn muốn hủy bỏ tại một số điểm bạn vẫn có thể làm điều đó với

handler.cancel();

Nó cũng tốt cho việc sử dụng sự kiện khác :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.