Created
July 8, 2012 16:22
-
-
Save mainyaa/3071608 to your computer and use it in GitHub Desktop.
Monkey patch for jQuery 1.7 to optimize animation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function ($) { | |
// Monkey patch for jQuery 1.7 to optimize animation | |
// Details: | |
// jQuery(this).is(":hidden")) access elem.offsetHeight property in each animation step. | |
// This patch enables lazy access to elem.offsetHeight property only when it is necessary. | |
// 2012/07/26: this patch is unnecessary on jQuery 1.8. fixed by https://github.com/jquery/jquery/pull/869 | |
var elemdisplay = {}, | |
iframe, iframeDoc, | |
rfxtypes = /^(?:toggle|show|hide)$/, | |
rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i, | |
timerId, | |
fxAttrs = [ | |
// height animations | |
[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ], | |
// width animations | |
[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ], | |
// opacity animations | |
[ "opacity" ] | |
], | |
fxNow; | |
$.fn._animate = $.fn.animate; | |
$.fn.animate = function( prop, speed, easing, callback ) { | |
var optall = jQuery.speed( speed, easing, callback ); | |
if ( jQuery.isEmptyObject( prop ) ) { | |
return this.each( optall.complete, [ false ] ); | |
} | |
// Do not change referenced properties as per-property easing will be lost | |
prop = jQuery.extend( {}, prop ); | |
function doAnimation() { | |
// XXX 'this' does not always have a nodeName when running the | |
// test suite | |
if ( optall.queue === false ) { | |
jQuery._mark( this ); | |
} | |
var opt = jQuery.extend( {}, optall ), | |
isElement = this.nodeType === 1, | |
hidden, name, val, p, e, | |
parts, start, end, unit, | |
method; | |
// will store per property easing and be used to determine when an animation is complete | |
opt.animatedProperties = {}; | |
for ( p in prop ) { | |
// property name normalization | |
name = jQuery.camelCase( p ); | |
if ( p !== name ) { | |
prop[ name ] = prop[ p ]; | |
delete prop[ p ]; | |
} | |
val = prop[ name ]; | |
// easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default) | |
if ( jQuery.isArray( val ) ) { | |
opt.animatedProperties[ name ] = val[ 1 ]; | |
val = prop[ name ] = val[ 0 ]; | |
} else { | |
opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing'; | |
} | |
if ( val === "hide" && (isElement && jQuery(this).is(":hidden")) || val === "show" && !(isElement && jQuery(this).is(":hidden")) ) { | |
return opt.complete.call( this ); | |
} | |
if ( isElement && ( name === "height" || name === "width" ) ) { | |
// Make sure that nothing sneaks out | |
// Record all 3 overflow attributes because IE does not | |
// change the overflow attribute when overflowX and | |
// overflowY are set to the same value | |
opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ]; | |
// Set display property to inline-block for height/width | |
// animations on inline elements that are having width/height animated | |
if ( jQuery.css( this, "display" ) === "inline" && | |
jQuery.css( this, "float" ) === "none" ) { | |
// inline-level elements accept inline-block; | |
// block-level elements need to be inline with layout | |
if ( !jQuery.support.inlineBlockNeedsLayout || defaultDisplay( this.nodeName ) === "inline" ) { | |
this.style.display = "inline-block"; | |
} else { | |
this.style.zoom = 1; | |
} | |
} | |
} | |
} | |
if ( opt.overflow != null ) { | |
this.style.overflow = "hidden"; | |
} | |
for ( p in prop ) { | |
if ( prop[ p ] === "toggle" ) { | |
hidden = (isElement && jQuery(this).is(":hidden")); | |
} | |
} | |
for ( p in prop ) { | |
e = new jQuery.fx( this, opt, p ); | |
val = prop[ p ]; | |
if ( rfxtypes.test( val ) ) { | |
// Tracks whether to show or hide based on private | |
// data attached to the element | |
method = jQuery._data( this, "toggle" + p ) || ( val === "toggle" ? hidden ? "show" : "hide" : 0 ); | |
if ( method ) { | |
jQuery._data( this, "toggle" + p, method === "show" ? "hide" : "show" ); | |
e[ method ](); | |
} else { | |
e[ val ](); | |
} | |
} else { | |
parts = rfxnum.exec( val ); | |
start = e.cur(); | |
if ( parts ) { | |
end = parseFloat( parts[2] ); | |
unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" ); | |
// We need to compute starting value | |
if ( unit !== "px" ) { | |
jQuery.style( this, p, (end || 1) + unit); | |
start = ( (end || 1) / e.cur() ) * start; | |
jQuery.style( this, p, start + unit); | |
} | |
// If a +=/-= token was provided, we're doing a relative animation | |
if ( parts[1] ) { | |
end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start; | |
} | |
e.custom( start, end, unit ); | |
} else { | |
e.custom( start, val, "" ); | |
} | |
} | |
} | |
// For JS strict compliance | |
return true; | |
} | |
return optall.queue === false ? | |
this.each( doAnimation ) : | |
this.queue( optall.queue, doAnimation ); | |
}; | |
})(jQuery); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(g){var l=/^(?:toggle|show|hide)$/,m=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i;g.fn._animate=g.fn.animate;g.fn.animate=function(d,g,n,o){function k(){var p;i.queue===!1&&jQuery._mark(this);var f=jQuery.extend({},i),e=this.nodeType===1,g,a,b,c,h,j;f.animatedProperties={};for(c in d){a=jQuery.camelCase(c);c!==a&&(d[a]=d[c],delete d[c]);b=d[a];jQuery.isArray(b)?(f.animatedProperties[a]=b[1],p=d[a]=b[0],b=p):f.animatedProperties[a]=f.specialEasing&&f.specialEasing[a]||f.easing||"swing";if(b==="hide"&& | |
e&&jQuery(this).is(":hidden")||b==="show"&&(!e||!jQuery(this).is(":hidden")))return f.complete.call(this);if(e&&(a==="height"||a==="width"))if(f.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],jQuery.css(this,"display")==="inline"&&jQuery.css(this,"float")==="none")!jQuery.support.inlineBlockNeedsLayout||defaultDisplay(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1}if(f.overflow!=null)this.style.overflow="hidden";for(c in d)d[c]==="toggle"&& | |
(g=e&&jQuery(this).is(":hidden"));for(c in d)if(e=new jQuery.fx(this,f,c),b=d[c],l.test(b))if(a=jQuery._data(this,"toggle"+c)||(b==="toggle"?g?"show":"hide":0))jQuery._data(this,"toggle"+c,a==="show"?"hide":"show"),e[a]();else e[b]();else a=m.exec(b),h=e.cur(),a?(b=parseFloat(a[2]),j=a[3]||(jQuery.cssNumber[c]?"":"px"),j!=="px"&&(jQuery.style(this,c,(b||1)+j),h*=(b||1)/e.cur(),jQuery.style(this,c,h+j)),a[1]&&(b=(a[1]==="-="?-1:1)*b+h),e.custom(h,b,j)):e.custom(h,b,"");return!0}var i=jQuery.speed(g, | |
n,o);if(jQuery.isEmptyObject(d))return this.each(i.complete,[!1]);d=jQuery.extend({},d);return i.queue===!1?this.each(k):this.queue(i.queue,k)}})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment