programing tip

브라우저에서 CSS3 전환 기능을 어떻게 정규화합니까?

itbloger 2020. 9. 7. 07:52
반응형

브라우저에서 CSS3 전환 기능을 어떻게 정규화합니까?


Webkit의 전환 종료 이벤트는 webkitTransitionEnd, Firefox는 transitionEnd, Opera는 oTransitionEnd입니다. 순수 JS에서 모두를 다루는 좋은 방법은 무엇입니까? 브라우저 스니핑을해야합니까? 또는 각각을 개별적으로 구현 하시겠습니까? 나에게 발생하지 않은 다른 방법?

즉 :

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

Modernizr에서 사용되는 기술이 개선되었습니다.

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

Matijs 의견에 따르면 전환 이벤트를 감지하는 가장 쉬운 방법은 라이브러리 인 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
}

최신 정보

다음은이를 수행하는 더 깨끗한 방법이며 모 더니 저가 필요하지 않습니다.

$(".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')];

이것은 Modernizr에서 제안한 코드를 기반으로하지만 최신 버전의 Opera에 대한 추가 이벤트가 있습니다.

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


If you use jQuery and Bootstrap $.support.transition.end will return the right event for the current browser.

It is defined in Bootstrap and used in its animation callbacks, though the jQuery docs say not to rely on these properties:

Although some of these properties are documented below, they are not subject to a long deprecation/removal cycle and may be removed once internal jQuery code no longer needs them.

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


As of 2015, this one-liner should do the deal (IE 10+, Chrome 1+, Safari 3.2+, FF 4+ and Opera 12+):-

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

Attaching the event listener is simple:-

element.addEventListener(transEndEventName , theFunctionToInvoke);

Here is a more cleaner way

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

The second is the way to go. Only one of those events will fire in every browser, so you can set all of them and it'll work.


google closure makes sure you don't have to do this. If you have an element:

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

looking at the source of goog.events.eventtype.js, TRANSITIONEND is calculated by looking at the useragent:

// 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'),

I use code like this (with 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
}

That lets me use JS to add things by specifying vP concatentated with the property, and if it didn't hit a browser it just uses the standard. The events lets me easily bind like so:

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

jquery override:

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

and usage like:

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

참고URL : https://stackoverflow.com/questions/5023514/how-do-i-normalize-css3-transition-functions-across-browsers

반응형