मैं ब्राउज़रों में CSS3 के संक्रमण कार्यों को कैसे सामान्य कर सकता हूं?


91

वेबकिट के संक्रमण अंत घटना को webkitTransitionEnd कहा जाता है, फ़ायरफ़ॉक्स ट्रांज़िशन है, और ओपेरा oTransitionEnd है। शुद्ध जेएस में उन सभी से निपटने का एक अच्छा तरीका क्या है? क्या मुझे ब्राउज़र सूँघना चाहिए? या हर एक को अलग से लागू करें? कोई और तरीका जो मेरे साथ नहीं हुआ है?

अर्थात:

//doing browser sniffing
var transitionend = (isSafari) ? "webkitTransitionEnd" : (isFirefox) ? "transitionEnd" : (isOpera) ? "oTransitionEnd";

element.addEventListener(transitionend, function(){
  //do whatever
},false);

या

// Assigning an event listener per browser
element.addEventListener("webkitTransitionEnd", fn);
element.addEventListener("oTransitionEnd", fn);
element.addEventListener("transitionEnd", fn);

function fn() {
   //do whatever
}

किस प्रयोजन के लिए असत्य है?
कॉल मी मी

जवाबों:


166

माडर्निज़्र में उपयोग की जाने वाली तकनीक में सुधार किया गया है:

function transitionEndEventName () {
    var i,
        undefined,
        el = document.createElement('div'),
        transitions = {
            'transition':'transitionend',
            'OTransition':'otransitionend',  // oTransitionEnd in very old Opera
            'MozTransition':'transitionend',
            'WebkitTransition':'webkitTransitionEnd'
        };

    for (i in transitions) {
        if (transitions.hasOwnProperty(i) && el.style[i] !== undefined) {
            return transitions[i];
        }
    }

    //TODO: throw 'TransitionEnd event is not supported in this browser'; 
}

जब भी आपको संक्रमण समाप्ति घटना की आवश्यकता हो तब आप इस फ़ंक्शन को कॉल कर सकते हैं:

var transitionEnd = transitionEndEventName();
element.addEventListener(transitionEnd, theFunctionToInvoke, false);

3
oTransitionEnd को ओपेरा में otransitionend पर उतारा गया। देखें opera.com/docs/specs/presto2.10/#m274
vieron

1
यह भी अब सभी लोअरकेस में संक्रमण है। देखें dev.w3.org/csswg/css3-transitions/#transition-events
gossi

1
मैंने MsTransition बिट को हटा दिया, लेकिन बाकी का जवाब चातुर्य में छोड़ दूंगा। सभी प्रमुख गैर-वेबकिट ब्राउज़रों के वर्तमान संस्करणों को एक विक्रेता उपसर्ग की आवश्यकता नहीं है। transitionऔर transitionendपर्याप्त हैं देखें: caniuse.com/#search=transitions
webinista

4
इसे फिर से परिभाषित करने की आवश्यकता क्यों है undefined?
Atav32

1
@ Atav32, मुझे आश्चर्य है कि भी। केवल एक चीज जो मैं सोच सकता हूं, वह यह है कि अगर किसी और ने इसे पहले से ही किसी और चीज के लिए फिर से परिभाषित कर लिया है।
क्यूटैक्स

22

मैटिज की टिप्पणी के अनुसार, संक्रमण की घटनाओं का पता लगाने का सबसे आसान तरीका एक पुस्तकालय के साथ है, इस मामले में jquery:

$("div").bind("webkitTransitionEnd.done oTransitionEnd.done otransitionend.done transitionend.done msTransitionEnd.done", function(){
  // Unlisten called events by namespace,
  // to prevent multiple event calls. (See comment)
  // By the way, .done can be anything you like ;)
  $(this).off('.done')
});

लाइब्रेरी-कम जावास्क्रिप्ट में यह थोड़ा वर्बोज़ हो जाता है:

element.addEventListener('webkitTransitionEnd', callfunction, false);
element.addEventListener('oTransitionEnd', callfunction, false);
element.addEventListener('transitionend', callfunction, false);
element.addEventListener('msTransitionEnd', callfunction, false);

function callfunction() {
   //do whatever
}

वह दूसरा-से-अंतिम एक ऊंट नहीं होना चाहिए।
6

7
काफी मजेदार है, मैं यहाँ आया क्योंकि मेरे सहयोगियों ने अपने कोड में कई घटनाओं की खोज की थी जो बिल्कुल इस उत्तर की तरह
दिखाई देती थीं

1
@Duopixel कृपया अपने उत्तर का परीक्षण करें और इसे बदलने पर विचार करें, क्योंकि यह Chrome और Safari (और कम से कम अन्य सभी वेबकिट ब्राउज़र प्लस पुराना फ़ायरफ़ॉक्स और ओपेरा) में दो ईवेंट फेंकता है। msTransitionendयहां जरूरत नहीं है।
दान

1
यदि आपके पास एक से अधिक संपत्ति है, तो यह कई घटनाओं को ट्रिगर करेगा। देखें: stackoverflow.com/a/18689069/740836
निक बुडेन

8

अपडेट करें

निम्नलिखित यह करने का एक क्लीनर तरीका है, और इसके लिए आधुनिकता की आवश्यकता नहीं है

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

वैकल्पिक रूप से

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

यह मॉर्डनिज़्र द्वारा सुझाए गए कोड पर आधारित है, लेकिन ओपेरा के नए संस्करणों के लिए अतिरिक्त घटना के साथ।

http://modernizr.com/docs/#prefixed


1
यह इसे करने का एक शानदार तरीका है लेकिन इसके लिए माडर्निज़र की आवश्यकता है। क्या यह सिर्फ़ आधुनिकता के बिना लिखा जा सकता है?
alt

2
jQuery संस्करण वेबकिट-आधारित ब्राउज़रों में दो घटनाओं को आग लगाता है (कम से कम)।
दान

2
@ मैं इसके बजाय एक का उपयोग करता हूं, इसलिए यह केवल एक बार आग लगाएगा
टॉम

क्षमा करें, मैंने आपको इसके oneबजाय नोटिस किया है on। इतना स्पष्ट था!
दान

8

यदि आप jQuery का उपयोग करते हैं और बूटस्ट्रैप $.support.transition.endवर्तमान ब्राउज़र के लिए सही घटना लौटाएगा।

इसे बूटस्ट्रैप में परिभाषित किया गया है और इसका एनीमेशन कॉलबैक में उपयोग किया गया है , हालांकि jQuery डॉक्स का कहना है कि इन गुणों पर भरोसा न करें:

हालाँकि इनमें से कुछ गुणों का दस्तावेजीकरण नीचे किया गया है, लेकिन वे लंबे समय के अपव्यय / निष्कासन चक्र के अधीन नहीं हैं और एक बार हटाए जाने के बाद आंतरिक jQuery कोड की आवश्यकता नहीं रह जाती है।

http://api.jquery.com/jQuery.support/


2
यहाँ सबसे सरल समाधान होने के नाते, यह एक वास्तविक शर्म की बात है कि इस तरह के एक चेतावनी है।
Ninjakannon

1
यह उनके कोड में यहाँ जोड़ा गया है github.com/twbs/bootstrap/blob/…
Tom

6

2015 तक, इस एक-लाइनर को सौदा करना चाहिए (आईई 10+, क्रोम 1+, सफारी 3.2+, एफएफ 4+ और ओपेरा 12 +): -

var transEndEventName = ('WebkitTransition' in document.documentElement.style) ? 'webkitTransitionEnd' : 'transitionend'

ईवेंट श्रोता को संलग्न करना सरल है: -

element.addEventListener(transEndEventName , theFunctionToInvoke);

लवली समाधान। दुर्भाग्य से यह आपको यह नहीं बताएगा कि क्या transitionendइसका समर्थन नहीं किया गया है: var transEndEventName = ('WebkitTransition' in document.documentElement.style) ? 'webkitTransitionEnd' : ('transitionend' in document.documentElement.style) ? 'transitionend' : false; और फिर एक साधारण जाँच करें: if(transEndEventName) element.addEventlistener(transEndEventName, theFunctionToInvoke)
Luuuud

मुझे लगता है कि अलग से जांच की जानी चाहिए: stackoverflow.com/a/29591030/362006
सलमान वॉन अब्बास

क्या यह उत्तर अब भी लागू होता है? (जनवरी २०१६)
जेसिका

बस IE 11 में इसका परीक्षण किया गया और यह झूठा लौट आया
जेसिका

1

दूसरा रास्ता है जाने का। उन ब्राउज़र में से केवल एक ही घटना में आग लग जाएगी, इसलिए आप उन सभी को सेट कर सकते हैं और यह काम करेगा।


1

यहाँ एक अधिक क्लीनर तरीका है

 function transitionEvent() {
      // Create a fake element
      var el = document.createElement("div");

      if(el.style.OTransition) return "oTransitionEnd";
      if(el.style.WebkitTransition) return "webkitTransitionEnd";
      return "transitionend";
    }

0

Google बंद करना सुनिश्चित करता है कि आपको ऐसा करने की आवश्यकता नहीं है। यदि आपके पास एक तत्व है:

goog.events.listen(element, goog.events.EventType.TRANSITIONEND, function(event) {
  // ... your code here
});

goog.events.eventtype.js के स्रोत को देखते हुए, TRANSITIONEND की गणना उपयोगकर्ता के पते को देखकर की जाती है:

// CSS transition events. Based on the browser support described at:
  // https://developer.mozilla.org/en/css/css_transitions#Browser_compatibility
  TRANSITIONEND: goog.userAgent.WEBKIT ? 'webkitTransitionEnd' :
      (goog.userAgent.OPERA ? 'oTransitionEnd' : 'transitionend'),

0

मैं इस तरह कोड का उपयोग करता हूं (jQuery के साथ)

var vP = "";
var transitionEnd = "transitionend";
if ($.browser.webkit) {
    vP = "-webkit-";
    transitionEnd = "webkitTransitionEnd";
} else if ($.browser.msie) {
    vP = "-ms-";
} else if ($.browser.mozilla) {
    vP = "-moz-";
} else if ($.browser.opera) {
    vP = "-o-";
    transitionEnd = "otransitionend"; //oTransitionEnd for very old Opera
}

मुझे संपत्ति के साथ वीपी को निर्दिष्ट करके चीजों को जोड़ने के लिए जेएस का उपयोग करने की अनुमति देता है, और अगर यह एक ब्राउज़र को हिट नहीं करता है तो यह मानक का उपयोग करता है। घटनाओं से मुझे आसानी से बाँधने की सुविधा मिलती है:

object.bind(transitionEnd,function(){
    callback();
});

धन्यवाद! मैंने ऐसा ही कुछ करना समाप्त कर दिया, लेकिन बिना ब्राउज़र सूँघे। आप परिणाम (और कोड) यहां देख सकते हैं: cssglue.com/cubic । आपके समाधान के साथ एकमात्र समस्या यह है कि - यदि ब्राउज़र विक्रेता अपने संक्रमण की घटनाओं को स्पष्ट करने का निर्णय लेते हैं - तो वे अपने उपसर्गों को छोड़ सकते हैं और वे काम करना बंद कर देंगे (संभावना नहीं, अभी तक)। लेकिन हाँ, यह कोड को बहुत अधिक क्लीनर बनाता है।
मेथोडिफिकेशन

मैं सहमत हूं, मेरा मतलब है कि मुझे कुछ बेहतर के साथ बदलना है, लेकिन दूसरी तरफ मुझे इसकी सरलता पसंद है।
रिच ब्रैडशॉ

2
हांलांकि इसकी कीमत के बारे निश्चित नहीं हूँ। यह बिना ब्राउजर object.bind('transitionend oTransitionEnd webkitTransitionEnd', function() { // callback } );
सूँघे

1
घटना के गैर-उपसर्गित संस्करण का नाम दिया गया है transitionend, नहीं TransitionEnd

0

jquery ओवरराइड:

(function ($) {
  var oldOn = $.fn.on;

  $.fn.on = function (types, selector, data, fn, /*INTERNAL*/ one) {
    if (types === 'transitionend') {
      types = 'transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd';
    }

    return oldOn.call(this, types, selector, data, fn, one);
  };
})(jQuery);

और उपयोग की तरह:

$('myDiv').on('transitionend', function() { ... });

0

स्वीकृत उत्तर सही है लेकिन आपको उस तत्व को फिर से और फिर से बनाने की जरूरत नहीं है ... और

एक वैश्विक चर बनाएँ और फ़ंक्शन जोड़ें:

(function(myLib, $, window, document, undefined){

/**
 * @summary
 * Returns the browser's supported animation end event type.
 * @desc
 * @see {@link https://jonsuh.com/blog/detect-the-end-of-css-animations-and-transitions-with-javascript/}
 * @function myLib.getAnimationEndType
 * @return {string} The animation end event type
 */
(function(){
   var type;

   myLib.getAnimationEndType = function(){
      if(!type)
         type = callback();
      return type;

      function callback(){
         var t,
             el = document.createElement("fakeelement");

         var animations = {
            "animation"      : "animationend",
            "OAnimation"     : "oAnimationEnd",
            "MozAnimation"   : "animationend",
            "WebkitAnimation": "webkitAnimationEnd"
         }

         for (t in animations){
            if (el.style[t] !== undefined){
               return animations[t];
            }
         }
      }
   }
}());

/**
 * @summary
 * Returns the browser's supported transition end event type.
 * @desc
 * @see {@link https://jonsuh.com/blog/detect-the-end-of-css-animations-and-transitions-with-javascript/}
 * @function myLib.getTransitionEndType
 * @return {string} The transition end event type
 */
(function(){
   var type;

   myLib.getTransitionEndType = function(){
      if(!type)
         type = callback();
      return type;

      function callback(){
         var t,
             el = document.createElement("fakeelement");

         var transitions = {
            "transition"      : "transitionend",
            "OTransition"     : "oTransitionEnd",
            "MozTransition"   : "transitionend",
            "WebkitTransition": "webkitTransitionEnd"
         }

         for (t in transitions){
            if (el.style[t] !== undefined){
               return transitions[t];
            }
         }
      }
   }
}());

}(window.myLib = window.myLib || {}, jQuery, window, document));
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.