เหตุการณ์การเปลี่ยนแปลง CSS3


คำตอบ:


210

W3C CSS Transitions Draft

ความสำเร็จของการเปลี่ยน CSS สร้างเหตุการณ์ DOM ที่สอดคล้องกัน เหตุการณ์ถูกเรียกใช้สำหรับแต่ละคุณสมบัติที่ผ่านช่วงการเปลี่ยนภาพ สิ่งนี้อนุญาตให้ผู้พัฒนาเนื้อหาดำเนินการที่ซิงโครไนซ์กับการเปลี่ยนภาพให้เสร็จสมบูรณ์


Webkit

ในการกำหนดว่าการเปลี่ยนแปลงจะเสร็จสมบูรณ์เมื่อใดให้ตั้งค่าฟังก์ชั่นฟังเหตุการณ์ JavaScript สำหรับเหตุการณ์ DOM ที่ส่งเมื่อสิ้นสุดการเปลี่ยนแปลง กรณีที่เป็นตัวอย่างของ WebKitTransitionEvent webkitTransitionEndและชนิดของมันคือ

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

Mozilla

มีเหตุการณ์เดียวที่เกิดขึ้นเมื่อการเปลี่ยนภาพเสร็จสมบูรณ์ ใน Firefox เหตุการณ์transitionendในโรงละครโอเปราoTransitionEndและใน WebKit webkitTransitionEndมันเป็น

อุปรากร

มีเหตุการณ์การเปลี่ยนแปลงประเภทหนึ่งที่มีอยู่ oTransitionEndเหตุการณ์ที่เกิดขึ้นในความสำเร็จของการเปลี่ยนแปลง

Internet Explorer

transitionendเหตุการณ์ที่เกิดขึ้นในความสำเร็จของการเปลี่ยนแปลง หากการเปลี่ยนแปลงถูกลบออกก่อนที่จะเสร็จสิ้นเหตุการณ์จะไม่เริ่มขึ้น


Stack Overflow: ฉันจะทำให้ฟังก์ชั่นการเปลี่ยน CSS3 เป็นปกติในเบราว์เซอร์ได้อย่างไร


3
โปรดทราบว่าเหตุการณ์นี้เรียกว่า "transitionend" ใน firefox และ "oTransitionEnd" ใน Opera
Andreas Köberle

8
ไม่มีใครพูดถึงสิ่งใดเกี่ยวกับส่วนเริ่มต้นการเปลี่ยนแปลงของคำถาม ไม่มีวิธีในการลงทะเบียนตัวจัดการเหตุการณ์ที่จะถูกไล่ออกก่อนที่การเปลี่ยนแปลงจะเริ่มต้นขึ้นหรือไม่?
tyler

ตอนนี้มีวิธีมาตรฐานในการบรรลุเป้าหมายนี้หรือไม่? ดูเหมือนว่า 2 ปีเป็นเวลานาน! สิ่งต่าง ๆ มีการเปลี่ยนแปลง
Fild อ่อน

@tyler ฉันไม่ทราบวิธีการแก้ไขการขาดการเปลี่ยน - เริ่มต้น
Davor Lucic

@Mild Fuzz ที่เชื่อมโยงกับคำถาม stackoverflow มีทางออกที่น่าสนใจ
Davor Lucic

73

ปรับปรุง

เบราว์เซอร์ที่ทันสมัยทั้งหมดนี้รองรับเหตุการณ์ที่ไม่ได้รับการแก้ไข:

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

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


ฉันใช้วิธีการที่กำหนดโดย Pete แต่ตอนนี้ฉันเริ่มใช้สิ่งต่อไปนี้แล้ว

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

หรือถ้าคุณใช้ bootstrap คุณก็สามารถทำได้

$(".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 จะถูกยิงมากกว่าหนึ่งครั้ง
เซบาสเตียน

11
ในเบราว์เซอร์ที่เก็บทั้งนำหน้าและชื่อเหตุการณ์ปกติรอบ ๆ คุณสามารถแก้ไขได้โดยใช้. 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.