Gọi lại khi chuyển đổi CSS


Câu trả lời:


82

Tôi biết rằng Safari triển khai một cuộc gọi lại webkitTransitionEnd mà bạn có thể đính kèm trực tiếp vào phần tử có quá trình chuyển đổi.

Ví dụ của họ (được định dạng lại thành nhiều dòng):

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

có điều tương tự cho trình duyệt khác sau đó webkit không?
meo

6
vâng, 'transitionend' cho Mozilla và 'oTransitionEnd' trong Opera.
qqryq

2
sai ở cuối làm gì?
meo

@meo Nó liên quan đến thisphần tử bên trong callback. Nhưng nó là một tham số bắt buộc, vì vậy trong trường hợp này, nó chỉ đáp ứng yêu cầu.
Doug Neiner

8
@DougNeiner Sai ở cuối là cho useCaptureMode. Khi một sự kiện xảy ra, có hai giai đoạn - giai đoạn đầu là chế độ chụp, giai đoạn thứ hai là chế độ bong bóng. Trong chế độ chụp, sự kiện giảm dần từ phần tử body đến phần tử được chỉ định. Sau đó, nó vào chế độ bong bóng, nơi nó thực hiện ngược lại. Thông số sai cuối cùng đó chỉ định rằng bạn muốn trình xử lý sự kiện xảy ra ở chế độ bong bóng. Một công dụng của điều này là đính kèm các trình xử lý sự kiện ngay trước khi chúng cần thiết ở chế độ bong bóng. =) 37signals.com/svn/posts/...
rybosome

103

Có, nếu những thứ như vậy được trình duyệt hỗ trợ, thì một sự kiện sẽ được kích hoạt khi quá trình chuyển đổi hoàn tất. Tuy nhiên, sự kiện thực tế khác nhau giữa các trình duyệt:

  • Sử dụng trình duyệt Webkit (Chrome, Safari) webkitTransitionEnd
  • Firefox sử dụng transitionend
  • IE9 + sử dụng msTransitionEnd
  • Opera sử dụng oTransitionEnd

Tuy nhiên, bạn nên biết rằng webkitTransitionEndkhông phải lúc nào cũng có lửa! Điều này đã khiến tôi bất ngờ một số lần và dường như xảy ra nếu hoạt ảnh không ảnh hưởng đến phần tử. Để giải quyết vấn đề này, bạn nên sử dụng thời gian chờ để kích hoạt trình xử lý sự kiện trong trường hợp nó không được kích hoạt như mong đợi. Bài đăng trên blog về sự cố này có sẵn tại đây: http://www.cuppadev.co.uk/the-trouble-with-css-transitions/ <- 500 Lỗi máy chủ nội bộ

Với suy nghĩ này, tôi có xu hướng sử dụng sự kiện này trong một đoạn mã trông giống như sau:

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) 

Lưu ý: để lấy tên kết thúc sự kiện chuyển đổi, bạn có thể sử dụng phương pháp được đăng dưới dạng câu trả lời trong: Làm cách nào để chuẩn hóa các chức năng Chuyển đổi CSS3 trên các trình duyệt? .

Lưu ý: câu hỏi này cũng liên quan đến: - Các sự kiện chuyển tiếp CSS3


2
Đây là một câu trả lời đầy đủ hơn nhiều so với câu trả lời được chấp nhận. Tại sao điều này không được ủng hộ nhiều hơn.
Wes

Hãy nhớ để gọi transitionEndedHandlertrong transitionEnded(hoặc thay đổi transitionEndedbởi transitionEndedHandlertrong addEventListenerremoveEventListenervà cuộc gọi transitionEndedtrong transitionEndedHandler)
Miquel

Cảm ơn @Miquel; nghĩ rằng tôi chỉ sử dụng transitionEndedkhi tôi muốn transitionEndedHandler.
Mark Rhodes,

Tôi tin rằng vấn đề Chromium cho vấn đề này có thể được tìm thấy tại đây: code.google.com/p/chromium/issues/detail?id=388082 Mặc dù, nhận xét cuối cùng dường như (theo quan điểm của tôi không chính xác) coi đó là lỗi và do đó nó hiện được đánh dấu là "sẽ không sửa chữa".
Willster

Ngày nay không cần các tên khác nhau caniuse.com/#feat=css-transitions
Juan Mendes

43

Tôi đang sử dụng mã sau, đơn giản hơn nhiều so với việc cố gắng phát hiện sự kiện kết thúc cụ thể nào mà trình duyệt sử dụng.

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

  // 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
Điều này chậm hơn vì nó phải tìm kiếm trong toàn bộ danh sách đó mỗi khi sự kiện xảy ra để xem nó có phải là danh sách chính xác hay không.
phreakhead

3
@phreakhead Hiệu suất của bất kỳ cách tiếp cận nào trong số này sẽ rất giống nhau
Tom

6

Các Plugin jQuery.transit , một plugin cho biến đổi CSS3 và hiệu ứng chuyển tiếp, có thể gọi hình ảnh động CSS của bạn từ kịch bản và cung cấp cho bạn một callback.


5

Điều này có thể dễ dàng đạt được với transitionendSự kiện xem tài liệu tại đây Một ví dụ đơn giản:

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
Đây là câu trả lời chính xác ngày nay, không cần phải có tiền tố nữa. caniuse.com/#feat=css-transitions
Juan Mendes
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.