Skip to content

Instantly share code, notes, and snippets.

@mach3
Last active December 22, 2015 21:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mach3/6536531 to your computer and use it in GitHub Desktop.
Save mach3/6536531 to your computer and use it in GitHub Desktop.
CSSのTransitionを$.fn.animateっぽく使うやつ。Transition非対応環境で$.fn.animateでそれっぽくフォールバックする。
(function($){
/**
* Detect support of css transition, event name
*/
$.support.transitionInfo = (function(){
var el, names, name, info = null;
el = document.createElement("div");
names = {
"WebkitTransition": "webkitTransitionEnd",
"MozTransition": "transitionend",
"OTransition": "oTransitionEnd otransitionend",
"transition": "transitionend"
};
for(name in names){
if(el.style[name] === ""){
info = { name: name, eventName: names[name] };
break;
}
}
return info;
}());
$.support.transition = $.support.transitionInfo !== null;
/**
* Map for easing functions
* If "jquery-easing" plugin imported, use one from them
*/
$.transitionEasings = (function(data){
$.each(data, function(key, names){
$.each(names, function(i, name){
if(typeof $.easing[name] === "function"){
data[key] = name;
return false;
}
});
});
return data;
}({
"ease": ["easeInOutQuad", "swing"],
"linear": ["linear"],
"ease-in": ["easeInCubic", "swing"],
"ease-out": ["easeOutCubic", "swing"],
"ease-in-out": ["easeInOutCubic", "swing"],
"common": ["swing"]
}));
/**
* Attach css transition like $.fn.animate
* If transition isn't supported, fallback with $.fn.animate
* When no arguments passed, return object which contains jquery-transition data
*
* @example:
* $(ele).transition({left: 100, opacity: 1}, {duration: 1000, easing: "ease"});
*
* @param Object styles
* @param Object options
*/
$.fn.transition = function(styles, options){
var transition;
options = $.extend({
delay: 0, // delay for animation
duration: 500, // duration for animation
easing: "ease-out", // easing function
done: $.noop // callback when done
}, options);
if($.support.transition){
transition = "all :duration :easing :delay"
.replace(":duration", (options.duration / 1000) + "s" )
.replace(":easing", options.easing)
.replace(":delay", (options.delay / 1000) + "s");
} else {
options.easing = $.transitionEasings[options.easing] || $.transitionEasing.common;
}
this.data("onTransitionEnd", options.done);
this.each(function(){
var node, eventName;
node = $(this);
if(! $.support.transition){
node.stop().delay(options.delay).animate(styles, options);
return;
}
eventName = $.support.transitionInfo.eventName;
node.css("transition", transition);
node.off(eventName);
node.on(eventName, function(e){
var node, handler;
node = $(this);
handler = node.data("onTransitionEnd");
node.css("transition", "");
node.off(e.type);
node.data("onTransitionEnd", undefined);
if($.isFunction(handler)){
handler.apply(this, arguments);
}
});
// fallback for the case nothing changed
setTimeout(
$.proxy(function(){
this.trigger($.support.transitionInfo.eventName);
}, node),
options.duration + 10
);
node.css(styles);
});
return this;
};
}(jQuery));
@mach3
Copy link
Author

mach3 commented Sep 12, 2013

コールバックの引数が環境でかわっちゃうので注意

@mach3
Copy link
Author

mach3 commented Sep 12, 2013

stylesが全く同じで変更がなされなかった場合に、これだとdone() がコールされずに次の引き継がれてしまう。それはよくない。

@mach3
Copy link
Author

mach3 commented Sep 12, 2013

bootstrapのtransition.jsを参考にサポートの判定を改善してみた。

@mach3
Copy link
Author

mach3 commented Sep 15, 2013

  • jquery-easing プラグインのeasingをサポートするようにしてみた
  • setTimeoutでstylesに変更がなかった場合のフォールバックを半ば強引に

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment