]> source.dussan.org Git - jquery.git/commitdiff
Fix #11755. Avoid :hidden selector for animations. Closes gh-774.
authorOleg <markelog@gmail.com>
Wed, 23 May 2012 02:36:55 +0000 (22:36 -0400)
committerDave Methvin <dave.methvin@gmail.com>
Wed, 23 May 2012 02:36:55 +0000 (22:36 -0400)
src/effects.js
test/unit/effects.js

index f7a317ac97f4b0a2bada42b51ed793601874ddcc..41e87e3af7d37c25cd89637658466109c7eb38fc 100644 (file)
@@ -216,7 +216,7 @@ function defaultPrefilter( elem, props, opts ) {
                style = elem.style,
                orig = {},
                handled = [],
-               hidden = jQuery( elem ).is(":hidden");
+               hidden = elem.nodeType && isHidden( elem );
 
        // height/width overflow pass
        if ( elem.nodeType === 1 && ( props.height || props.width ) ) {
@@ -373,6 +373,11 @@ Tween.propHooks = {
        }
 };
 
+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 = [],
@@ -395,9 +400,8 @@ function showHide( elements, show ) {
                        // 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 === "" && jQuery.css( elem, "display" ) === "none") ||
-                               !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
-                               values[ index ] = jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
+                       if ( elem.style.display === "" && isHidden( elem ) ) {
+                               values[ index ] = jQuery._data( elem, "olddisplay", defaultDisplay( elem.nodeName ) );
                        }
                } else {
                        display = jQuery.css( elem, "display" );
@@ -442,7 +446,7 @@ jQuery.fn.extend({
 
                } else if ( fn == null || bool ) {
                        this.each(function() {
-                               var state = bool ? fn : jQuery( this ).is(":hidden");
+                               var state = bool ? fn : isHidden( this );
                                showHide([ this ], state );
                        });
 
@@ -453,8 +457,12 @@ jQuery.fn.extend({
                return this;
        },
        fadeTo: function( speed, to, easing, callback ) {
-               return this.filter(":hidden").css("opacity", 0).show().end()
-                                       .animate({opacity: to}, speed, 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 ),
index b05dfa0cfff037861ca6a7aef5e40c79e57bfed6..fed25eeb0124ab37567a85a15e57057d90d310d1 100644 (file)
@@ -1480,7 +1480,6 @@ asyncTest( "Animate Option: step: function( percent, tween )", 1, function() {
        });
 });
 
-
 asyncTest( "Animate callbacks have correct context", 2, function() {
        var foo = jQuery( "#foo" );
        foo.animate({
@@ -1510,6 +1509,67 @@ asyncTest( "User supplied callback called after show when fx off (#8892)", 2, fu
        });
 });
 
+test( "animate should set display for disconnected nodes", function() {
+       expect( 18 );
+
+       var i = 0,
+               methods = {
+                       toggle: [ 1 ],
+                       slideToggle: [],
+                       fadeIn: [],
+                       fadeTo: [ "fast", 0.5 ],
+                       slideDown: [ "fast" ],
+                       show: [ 1 ],
+                       animate: [{ width: "show" }]
+               },
+               elems = [
+
+                       // parentNode = document fragment
+                       jQuery("<div>test</div>"),
+
+                       // parentNode = null
+                       jQuery("<div/>"),
+
+                       jQuery('<div style="display:inline"/>'),
+
+                       jQuery('<div style="display:none"/>')
+               ];
+
+       strictEqual( elems[ 0 ].show()[ 0 ].style.display, "block", "set display with show() for element with parentNode = document fragment" );
+       strictEqual( elems[ 1 ].show()[ 0 ].style.display, "block", "set display with show() for element with parentNode = null" );
+       strictEqual( elems[ 2 ].show()[ 0 ].style.display, "inline", "show() should not change display if it already set" );
+       strictEqual( elems[ 3 ].show()[ 0 ].style.display, "block", "show() should change display if it already set to none" );
+
+       // cleanup
+       jQuery.each( elems, function() {
+               jQuery.removeData( this[ 0 ], "olddisplay", true );
+       });
+
+       stop();
+       jQuery.each( methods, function( name, opt ) {
+               jQuery.each([
+
+                       // parentNode = document fragment
+                       jQuery("<div>test</div>"),
+
+                       // parentNode = null
+                       jQuery("<div/>")
+
+               ], function() {
+                       var callback = [function () {
+                                       strictEqual( this.style.display, "block", "set display to block with " + name );
+
+                                       jQuery.removeData( this, "olddisplay", true );
+
+                                       if ( ++i === 14 ) {
+                                               start();
+                                       }
+                       }];
+                       jQuery.fn[ name ].apply( this, opt.concat( callback ) );
+               });
+       });
+});
+
 asyncTest("Animation callback should not show animated element as animated (#7157)", 1, function() {
        var foo = jQuery( "#foo" );
 
@@ -1519,4 +1579,52 @@ asyncTest("Animation callback should not show animated element as animated (#715
                ok( !foo.is(':animated'), "The element is not animated" );
                start();
        });
-});
\ No newline at end of file
+});
+
+asyncTest( "hide called on element within hidden parent should set display to none (#10045)", 3, function() {
+       var hidden = jQuery(".hidden"),
+               elems = jQuery("<div>hide</div><div>hide0</div><div>hide1</div>");
+
+       hidden.append( elems );
+
+       jQuery.when(
+               elems.eq( 0 ).hide(),
+               elems.eq( 1 ).hide( 0 ),
+               elems.eq( 2 ).hide( 1 )
+       ).done(function() {
+               strictEqual( elems.get( 0 ).style.display, "none", "hide() called on element within hidden parent should set display to none" );
+               strictEqual( elems.get( 1 ).style.display, "none", "hide( 0 ) called on element within hidden parent should set display to none" );
+               strictEqual( elems.get( 2 ).style.display, "none", "hide( 1 ) called on element within hidden parent should set display to none" );
+
+               start();
+       });
+});
+
+asyncTest( "hide, fadeOut and slideUp called on element width height and width = 0 should set display to none", 5, function() {
+       var foo = jQuery("#foo"),
+               i = 0,
+               elems = jQuery();
+
+       for ( ; i < 5; i++ ) {
+               elems = elems.add('<div style="width:0;height:0;"></div>');
+       }
+
+       foo.append( elems );
+
+       jQuery.when(
+               elems.eq( 0 ).hide(),
+               elems.eq( 1 ).hide( jQuery.noop ),
+               elems.eq( 2 ).hide( 1 ),
+               elems.eq( 3 ).fadeOut(),
+               elems.eq( 4 ).slideUp()
+       ).done(function() {
+               strictEqual( elems.get( 0 ).style.display, "none", "hide() called on element width height and width = 0 should set display to none" );
+               strictEqual( elems.get( 1 ).style.display, "none",
+                                                                                               "hide( jQuery.noop ) called on element width height and width = 0 should set display to none" );
+               strictEqual( elems.get( 2 ).style.display, "none", "hide( 1 ) called on element width height and width = 0 should set display to none" );
+               strictEqual( elems.get( 3 ).style.display, "none", "fadeOut() called on element width height and width = 0 should set display to none" );
+               strictEqual( elems.get( 4 ).style.display, "none", "slideUp() called on element width height and width = 0 should set display to none" );
+
+               start();
+       });
+});