mirror of
https://github.com/jquery/jquery.git
synced 2024-10-05 11:34:18 +00:00
711 lines
18 KiB
JavaScript
711 lines
18 KiB
JavaScript
(function( jQuery ) {
|
|
|
|
var fxNow, timerId, iframe, iframeDoc,
|
|
elemdisplay = {},
|
|
rfxtypes = /^(?:toggle|show|hide)$/,
|
|
rfxnum = /^([\-+]=)?((?:\d*\.)?\d+)([a-z%]*)$/i,
|
|
rrun = /\.run$/,
|
|
animationPrefilters = [ defaultPrefilter ],
|
|
tweeners = {
|
|
"*": [function( prop, value ) {
|
|
var end, unit,
|
|
tween = this.createTween( prop, value ),
|
|
parts = rfxnum.exec( value ),
|
|
start = tween.cur();
|
|
|
|
if ( parts ) {
|
|
end = +parts[2];
|
|
unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" );
|
|
|
|
// We need to compute starting value
|
|
if ( unit !== "px" ) {
|
|
jQuery.style( this, prop, (end || 1) + unit);
|
|
start = start * (end || 1) / tween.cur() || 0;
|
|
jQuery.style( this, prop, start + unit);
|
|
}
|
|
|
|
tween.unit = unit;
|
|
tween.start = start;
|
|
// If a +=/-= token was provided, we're doing a relative animation
|
|
tween.end = parts[1] ? start + end * ( parts[1] === "-=" ? -1 : 1 ) : end;
|
|
}
|
|
return tween;
|
|
}]
|
|
},
|
|
oldToggle = jQuery.fn.toggle;
|
|
|
|
// Animations created synchronously will run synchronously
|
|
function createFxNow() {
|
|
setTimeout(function() {
|
|
fxNow = undefined;
|
|
}, 0 );
|
|
return ( fxNow = jQuery.now() );
|
|
}
|
|
|
|
function callTweeners( animation, props ) {
|
|
jQuery.each( props, function( prop, value ) {
|
|
var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
|
|
index = 0,
|
|
length = collection.length;
|
|
for ( ; index < length; index++ ) {
|
|
if ( collection[ index ].call( animation, prop, value ) ) {
|
|
|
|
// we're done with this property
|
|
return;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function Animation( elem, properties, options ) {
|
|
var result,
|
|
index = 0,
|
|
tweenerIndex = 0,
|
|
length = animationPrefilters.length,
|
|
finished = jQuery.Deferred(),
|
|
deferred = jQuery.Deferred().always(function( ended ) {
|
|
|
|
// don't match elem in the :animated selector
|
|
delete tick.elem;
|
|
if ( deferred.state() === "resolved" || ended ) {
|
|
|
|
// fire callbacks
|
|
finished.resolveWith( this );
|
|
}
|
|
}),
|
|
tick = function() {
|
|
var currentTime = fxNow || createFxNow(),
|
|
remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
|
|
percent = 1 - ( remaining / animation.duration || 0 ),
|
|
index = 0,
|
|
length = animation.tweens.length;
|
|
|
|
for ( ; index < length ; index++ ) {
|
|
animation.tweens[ index ].run( percent );
|
|
}
|
|
|
|
if ( percent < 1 && length ) {
|
|
return remaining;
|
|
} else {
|
|
deferred.resolveWith( elem, [ currentTime ] );
|
|
return false;
|
|
}
|
|
},
|
|
animation = deferred.promise({
|
|
elem: elem,
|
|
props: jQuery.extend( {}, properties ),
|
|
opts: jQuery.extend( true, { specialEasing: {} }, options ),
|
|
originalProperties: properties,
|
|
originalOptions: options,
|
|
startTime: fxNow || createFxNow(),
|
|
duration: options.duration,
|
|
finish: finished.done,
|
|
tweens: [],
|
|
createTween: function( prop, end, easing ) {
|
|
var tween = jQuery.Tween( elem, animation.opts, prop, end,
|
|
animation.opts.specialEasing[ prop ] || animation.opts.easing );
|
|
animation.tweens.push( tween );
|
|
return tween;
|
|
},
|
|
stop: function( gotoEnd ) {
|
|
var index = 0,
|
|
// if we are going to the end, we want to run all the tweens
|
|
// otherwise we skip this part
|
|
length = gotoEnd ? animation.tweens.length : 0;
|
|
|
|
for ( ; index < length ; index++ ) {
|
|
animation.tweens[ index ].run( 1 );
|
|
}
|
|
deferred.rejectWith( elem, [ gotoEnd ] );
|
|
return this;
|
|
}
|
|
}),
|
|
props = animation.props;
|
|
|
|
propFilter( props, animation.opts.specialEasing );
|
|
|
|
for ( ; index < length ; index++ ) {
|
|
result = animationPrefilters[ index ].call( animation,
|
|
elem, props, animation.opts );
|
|
if ( result ) {
|
|
return result;
|
|
}
|
|
}
|
|
|
|
callTweeners( animation, props );
|
|
|
|
jQuery.fx.timer(
|
|
jQuery.extend( tick, {
|
|
anim: animation,
|
|
queue: animation.opts.queue,
|
|
elem: elem
|
|
})
|
|
);
|
|
return animation;
|
|
}
|
|
|
|
function propFilter( props, specialEasing ) {
|
|
var index, name, easing, value, hooks;
|
|
|
|
// camelCase, specialEasing and expand cssHook pass
|
|
for ( index in props ) {
|
|
name = jQuery.camelCase( index );
|
|
easing = specialEasing[ name ];
|
|
value = props[ index ];
|
|
if ( jQuery.isArray( value ) ) {
|
|
easing = value[ 1 ];
|
|
value = props[ index ] = value[ 0 ];
|
|
}
|
|
|
|
if ( index !== name ) {
|
|
props[ name ] = value;
|
|
delete props[ index ];
|
|
}
|
|
|
|
hooks = jQuery.cssHooks[ name ];
|
|
if ( hooks && "expand" in hooks ) {
|
|
value = hooks.expand( value );
|
|
delete props[ name ];
|
|
|
|
// not quite $.extend, this wont overwrite keys already present.
|
|
// also - reusing 'index' from above because we have the correct "name"
|
|
for ( index in value ) {
|
|
if ( !( index in props ) ) {
|
|
props[ index ] = value[ index ];
|
|
specialEasing[ index ] = easing;
|
|
}
|
|
}
|
|
} else {
|
|
specialEasing[ name ] = easing;
|
|
}
|
|
}
|
|
}
|
|
|
|
jQuery.Animation = jQuery.extend( Animation, {
|
|
|
|
tweener: function( props, callback ) {
|
|
if ( jQuery.isFunction( props ) ) {
|
|
callback = props;
|
|
props = [ "*" ];
|
|
} else {
|
|
props = props.split(" ");
|
|
}
|
|
|
|
var prop,
|
|
index = 0,
|
|
length = props.length;
|
|
|
|
for ( ; index < length ; index++ ) {
|
|
prop = props[ index ];
|
|
tweeners[ prop ] = tweeners[ prop ] || [];
|
|
tweeners[ prop ].unshift( callback );
|
|
}
|
|
},
|
|
|
|
prefilter: function( callback, prepend ) {
|
|
if ( prepend ) {
|
|
animationPrefilters.unshift( callback );
|
|
} else {
|
|
animationPrefilters.push( callback );
|
|
}
|
|
}
|
|
});
|
|
|
|
function defaultPrefilter( elem, props, opts ) {
|
|
var index, prop, value, length, dataShow, tween,
|
|
style = elem.style,
|
|
orig = {},
|
|
handled = [],
|
|
hidden = elem.nodeType && isHidden( elem );
|
|
|
|
// height/width overflow pass
|
|
if ( elem.nodeType === 1 && ( props.height || props.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
|
|
opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
|
|
|
|
// Set display property to inline-block for height/width
|
|
// animations on inline elements that are having width/height animated
|
|
if ( jQuery.css( elem, "display" ) === "inline" &&
|
|
jQuery.css( elem, "float" ) === "none" ) {
|
|
|
|
// inline-level elements accept inline-block;
|
|
// block-level elements need to be inline with layout
|
|
if ( !jQuery.support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
|
|
style.display = "inline-block";
|
|
|
|
} else {
|
|
style.zoom = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( opts.overflow ) {
|
|
style.overflow = "hidden";
|
|
this.finish(function() {
|
|
style.overflow = opts.overflow[ 0 ];
|
|
style.overflowX = opts.overflow[ 1 ];
|
|
style.overflowY = opts.overflow[ 2 ];
|
|
});
|
|
}
|
|
|
|
|
|
// show/hide pass
|
|
for ( index in props ) {
|
|
value = props[ index ];
|
|
if ( rfxtypes.exec( value ) ) {
|
|
delete props[ index ];
|
|
if ( value === ( hidden ? "hide" : "show" ) ) {
|
|
continue;
|
|
}
|
|
handled.push( index );
|
|
}
|
|
}
|
|
|
|
length = handled.length;
|
|
if ( length ) {
|
|
dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} );
|
|
if ( hidden ) {
|
|
showHide([ elem ], true );
|
|
} else {
|
|
this.finish(function() {
|
|
showHide([ elem ]);
|
|
});
|
|
}
|
|
this.finish(function() {
|
|
var prop;
|
|
jQuery.removeData( elem, "fxshow", true );
|
|
for ( prop in orig ) {
|
|
jQuery.style( elem, prop, orig[ prop ] );
|
|
}
|
|
});
|
|
for ( index = 0 ; index < length ; index++ ) {
|
|
prop = handled[ index ];
|
|
tween = this.createTween( prop, hidden ? dataShow[ prop ] : 0 );
|
|
orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop );
|
|
|
|
if ( !( prop in dataShow ) ) {
|
|
dataShow[ prop ] = tween.start;
|
|
if ( hidden ) {
|
|
tween.end = tween.start;
|
|
tween.start = prop === "width" || prop === "height" ? 1 : 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function Tween( elem, options, prop, end, easing ) {
|
|
return new Tween.prototype.init( elem, options, prop, end, easing );
|
|
}
|
|
jQuery.Tween = Tween;
|
|
|
|
Tween.prototype = {
|
|
constructor: Tween,
|
|
init: function( elem, options, prop, end, easing, unit ) {
|
|
this.elem = elem;
|
|
this.prop = prop;
|
|
this.easing = easing || "swing";
|
|
this.options = options;
|
|
this.start = this.now = this.cur();
|
|
this.end = end;
|
|
this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
|
|
},
|
|
cur: function() {
|
|
var hooks = Tween.propHooks[ this.prop ];
|
|
|
|
return hooks && hooks.get ?
|
|
hooks.get( this ) :
|
|
Tween.propHooks._default.get( this );
|
|
},
|
|
run: function( percent ) {
|
|
var eased,
|
|
hooks = Tween.propHooks[ this.prop ];
|
|
|
|
this.pos = eased = jQuery.easing[ this.easing ]( percent, this.options.duration * percent, 0, 1, this.options.duration );
|
|
this.now = ( this.end - this.start ) * eased + this.start;
|
|
|
|
if ( this.options.step ) {
|
|
this.options.step.call( this.elem, this.now, this );
|
|
}
|
|
|
|
if ( hooks && hooks.set ) {
|
|
hooks.set( this );
|
|
} else {
|
|
Tween.propHooks._default.set( this );
|
|
}
|
|
return this;
|
|
}
|
|
};
|
|
|
|
Tween.prototype.init.prototype = Tween.prototype;
|
|
|
|
Tween.propHooks = {
|
|
_default: {
|
|
get: function( tween ) {
|
|
var parsed, result;
|
|
|
|
if ( tween.elem[ tween.prop ] != null &&
|
|
(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
|
|
return tween.elem[ tween.prop ];
|
|
}
|
|
|
|
result = jQuery.css( tween.elem, tween.prop );
|
|
// Empty strings, null, undefined and "auto" are converted to 0,
|
|
// complex values such as "rotate(1rad)" are returned as is,
|
|
// simple values such as "10px" are parsed to Float.
|
|
return isNaN( parsed = parseFloat( result ) ) ?
|
|
!result || result === "auto" ? 0 : result : parsed;
|
|
},
|
|
set: function( tween ) {
|
|
// use step hook for back compat - use cssHook if its there - use .style if its
|
|
// available and use plain properties where available
|
|
if ( jQuery.fx.step[ tween.prop ] ) {
|
|
jQuery.fx.step[ tween.prop ]( tween );
|
|
} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
|
|
jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
|
|
} else {
|
|
tween.elem[ tween.prop ] = tween.now;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
function isHidden( elem, el ) {
|
|
elem = el || elem;
|
|
return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument.documentElement, elem );
|
|
}
|
|
|
|
function showHide( elements, show ) {
|
|
var elem, display,
|
|
values = [],
|
|
index = 0,
|
|
length = elements.length;
|
|
|
|
for ( ; index < length; index++ ) {
|
|
elem = elements[ index ];
|
|
if ( !elem.style ) {
|
|
continue;
|
|
}
|
|
values[ index ] = jQuery._data( elem, "olddisplay" );
|
|
if ( show ) {
|
|
// Reset the inline display of this element to learn if it is
|
|
// being hidden by cascaded rules or not
|
|
if ( !values[ index ] && elem.style.display === "none" ) {
|
|
elem.style.display = "";
|
|
}
|
|
|
|
// Set elements which have been overridden with display: none
|
|
// in a stylesheet to whatever the default browser style is
|
|
// for such an element
|
|
if ( elem.style.display === "" && isHidden( elem ) ) {
|
|
values[ index ] = jQuery._data( elem, "olddisplay", defaultDisplay( elem.nodeName ) );
|
|
}
|
|
} else {
|
|
display = jQuery.css( elem, "display" );
|
|
|
|
if ( !values[ index ] && display !== "none" ) {
|
|
jQuery._data( elem, "olddisplay", display );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set the display of most of the elements in a second loop
|
|
// to avoid the constant reflow
|
|
for ( index = 0; index < length; index++ ) {
|
|
elem = elements[ index ];
|
|
if ( !elem.style ) {
|
|
continue;
|
|
}
|
|
if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
|
|
elem.style.display = show ? values[ index ] || "" : "none";
|
|
}
|
|
}
|
|
|
|
return elements;
|
|
}
|
|
|
|
jQuery.fn.extend({
|
|
show: function( speed, easing, callback ) {
|
|
return speed || speed === 0 ?
|
|
this.animate( genFx( "show", true ), speed, easing, callback ) :
|
|
showHide( this, true );
|
|
},
|
|
hide: function( speed, easing, callback ) {
|
|
return speed || speed === 0 ?
|
|
this.animate( genFx( "hide", true ), speed, easing, callback ) :
|
|
showHide( this );
|
|
},
|
|
toggle: function( fn, fn2, callback ) {
|
|
var bool = typeof fn === "boolean";
|
|
|
|
if ( jQuery.isFunction( fn ) && jQuery.isFunction( fn2 ) ) {
|
|
oldToggle.apply( this, arguments );
|
|
|
|
} else if ( fn == null || bool ) {
|
|
this.each(function() {
|
|
var state = bool ? fn : isHidden( this );
|
|
showHide([ this ], state );
|
|
});
|
|
|
|
} else {
|
|
this.animate( genFx( "toggle", true ), fn, fn2, callback );
|
|
}
|
|
|
|
return this;
|
|
},
|
|
fadeTo: function( speed, to, easing, callback ) {
|
|
|
|
// show any hidden elements after setting opacity to 0
|
|
return this.filter( isHidden ).css( "opacity", 0 ).show()
|
|
|
|
// animate to the value specified
|
|
.end().animate({ opacity: to }, speed, easing, callback );
|
|
},
|
|
animate: function( prop, speed, easing, callback ) {
|
|
var optall = jQuery.speed( speed, easing, callback ),
|
|
doAnimation = function() {
|
|
Animation( this, prop, optall ).finish( optall.complete );
|
|
};
|
|
|
|
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 );
|
|
|
|
return optall.queue === false ?
|
|
this.each( doAnimation ) :
|
|
this.queue( optall.queue, doAnimation );
|
|
},
|
|
stop: function( type, clearQueue, gotoEnd ) {
|
|
var stopQueue = function( elem, data, index ) {
|
|
var hooks = data[ index ];
|
|
jQuery.removeData( elem, index, true );
|
|
hooks.stop( gotoEnd );
|
|
};
|
|
|
|
if ( typeof type !== "string" ) {
|
|
gotoEnd = clearQueue;
|
|
clearQueue = type;
|
|
type = undefined;
|
|
}
|
|
if ( clearQueue && type !== false ) {
|
|
this.queue( type || "fx", [] );
|
|
}
|
|
|
|
return this.each(function() {
|
|
var index,
|
|
hadTimers = false,
|
|
timers = jQuery.timers,
|
|
data = jQuery._data( this );
|
|
|
|
// clear marker counters if we know they won't be
|
|
if ( !gotoEnd ) {
|
|
jQuery._unmark( true, this );
|
|
}
|
|
|
|
if ( type == null ) {
|
|
for ( index in data ) {
|
|
if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
|
|
stopQueue( this, data, index );
|
|
}
|
|
}
|
|
} else if ( data[ index = type + ".run" ] && data[ index ].stop ){
|
|
stopQueue( this, data, index );
|
|
}
|
|
|
|
for ( index = timers.length; index--; ) {
|
|
if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
|
|
timers[ index ].anim.stop( gotoEnd );
|
|
hadTimers = true;
|
|
timers.splice( index, 1 );
|
|
}
|
|
}
|
|
|
|
// start the next in the queue if the last step wasn't forced
|
|
// timers currently will call their complete callbacks, which will dequeue
|
|
// but only if they were gotoEnd
|
|
if ( !( gotoEnd && hadTimers ) ) {
|
|
jQuery.dequeue( this, type );
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
// Generate parameters to create a standard animation
|
|
function genFx( type, includeWidth ) {
|
|
var which,
|
|
attrs = { height: type },
|
|
i = 0;
|
|
|
|
// if we include width, step value is 1 to do all cssExpand values,
|
|
// if we don't include width, step value is 2 to skip over Left and Right
|
|
for( ; i < 4 ; i += 2 - includeWidth ) {
|
|
which = jQuery.cssExpand[ i ];
|
|
attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
|
|
}
|
|
|
|
if ( includeWidth ) {
|
|
attrs.opacity = attrs.width = type;
|
|
}
|
|
|
|
return attrs;
|
|
}
|
|
|
|
// Generate shortcuts for custom animations
|
|
jQuery.each({
|
|
slideDown: genFx("show"),
|
|
slideUp: genFx("hide"),
|
|
slideToggle: genFx("toggle"),
|
|
fadeIn: { opacity: "show" },
|
|
fadeOut: { opacity: "hide" },
|
|
fadeToggle: { opacity: "toggle" }
|
|
}, function( name, props ) {
|
|
jQuery.fn[ name ] = function( speed, easing, callback ) {
|
|
return this.animate( props, speed, easing, callback );
|
|
};
|
|
});
|
|
|
|
jQuery.speed = function( speed, easing, fn ) {
|
|
var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
|
|
complete: fn || !fn && easing ||
|
|
jQuery.isFunction( speed ) && speed,
|
|
duration: speed,
|
|
easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
|
|
};
|
|
|
|
opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
|
|
opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
|
|
|
|
// normalize opt.queue - true/undefined/null -> "fx"
|
|
if ( opt.queue == null || opt.queue === true ) {
|
|
opt.queue = "fx";
|
|
}
|
|
|
|
// Queueing
|
|
opt.old = opt.complete;
|
|
|
|
opt.complete = function( noUnmark ) {
|
|
if ( jQuery.isFunction( opt.old ) ) {
|
|
opt.old.call( this );
|
|
}
|
|
|
|
if ( opt.queue ) {
|
|
jQuery.dequeue( this, opt.queue );
|
|
} else if ( noUnmark !== false ) {
|
|
jQuery._unmark( this );
|
|
}
|
|
};
|
|
|
|
return opt;
|
|
};
|
|
|
|
jQuery.easing = {
|
|
linear: function( p ) {
|
|
return p;
|
|
},
|
|
swing: function( p ) {
|
|
return 0.5 - Math.cos( p*Math.PI ) / 2;
|
|
}
|
|
};
|
|
|
|
jQuery.timers = [];
|
|
jQuery.fx = Tween.prototype.init;
|
|
jQuery.fx.tick = function() {
|
|
var timer,
|
|
timers = jQuery.timers,
|
|
i = 0;
|
|
|
|
for ( ; i < timers.length; i++ ) {
|
|
timer = timers[ i ];
|
|
// Checks the timer has not already been removed
|
|
if ( !timer() && timers[ i ] === timer ) {
|
|
timers.splice( i--, 1 );
|
|
}
|
|
}
|
|
|
|
if ( !timers.length ) {
|
|
jQuery.fx.stop();
|
|
}
|
|
};
|
|
|
|
jQuery.fx.timer = function( timer ) {
|
|
if ( timer() && jQuery.timers.push( timer ) && !timerId ) {
|
|
timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
|
|
}
|
|
};
|
|
|
|
jQuery.fx.interval = 13;
|
|
|
|
jQuery.fx.stop = function() {
|
|
clearInterval( timerId );
|
|
timerId = null;
|
|
};
|
|
|
|
jQuery.fx.speeds = {
|
|
slow: 600,
|
|
fast: 200,
|
|
// Default speed
|
|
_default: 400
|
|
};
|
|
|
|
// Back Compat <1.8 extension point
|
|
jQuery.fx.step = {};
|
|
|
|
if ( jQuery.expr && jQuery.expr.filters ) {
|
|
jQuery.expr.filters.animated = function( elem ) {
|
|
return jQuery.grep(jQuery.timers, function( fn ) {
|
|
return elem === fn.elem;
|
|
}).length;
|
|
};
|
|
}
|
|
|
|
// Try to restore the default display value of an element
|
|
function defaultDisplay( nodeName ) {
|
|
if ( elemdisplay[ nodeName ] ) {
|
|
return elemdisplay[ nodeName ];
|
|
}
|
|
|
|
var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ),
|
|
display = elem.css("display");
|
|
elem.remove();
|
|
|
|
// If the simple way fails,
|
|
// get element's real default display by attaching it to a temp iframe
|
|
if ( display === "none" || display === "" ) {
|
|
// Use the already-created iframe if possible
|
|
iframe = document.body.appendChild(
|
|
iframe || jQuery.extend( document.createElement("iframe"), {
|
|
frameBorder: 0,
|
|
width: 0,
|
|
height: 0
|
|
})
|
|
);
|
|
|
|
// Create a cacheable copy of the iframe document on first call.
|
|
// IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
|
|
// document to it; WebKit & Firefox won't allow reusing the iframe document.
|
|
if ( !iframeDoc || !iframe.createElement ) {
|
|
iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
|
|
iframeDoc.write("<!doctype html><html><body>");
|
|
iframeDoc.close();
|
|
}
|
|
|
|
elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) );
|
|
|
|
display = jQuery.css( elem, "display" );
|
|
document.body.removeChild( iframe );
|
|
}
|
|
|
|
// Store the correct default display
|
|
elemdisplay[ nodeName ] = display;
|
|
|
|
return display;
|
|
}
|
|
|
|
})( jQuery );
|