Skip to main content

Bug Tracker

Side navigation

#2233 closed bug (duplicate)

Opened January 24, 2008 07:50PM UTC

Closed December 19, 2008 06:12PM UTC

Last modified March 15, 2012 10:14AM UTC

.hide() on a new element does not work in safari

Reported by: tmm1 Owned by:
Priority: major Milestone: 1.3
Component: core Version: 1.2.6
Keywords: Cc:
Blocked by: Blocking:
Description

Adding a new hidden element to the DOM using .append() does not work as expected in Safari 3

$('body').append( $('<div>').text('hi').hide() )

will insert a new div which is not hidden. This is only with Safari 3, FF and IE work fine.

The following alternative does work in Safari:

$('body').append( $('<div style="display:none;">').text('hi') )

Attachments (0)
Change History (8)

Changed January 24, 2008 08:04PM UTC by tmm1 comment:1

This is due to the :visible selector being broken in Safari when an element is not part of the DOM yet.

Changed January 24, 2008 10:04PM UTC by davidserduke comment:2

This should work too:

$('body').append( $('<div/>').text('hi').css('display', 'none') )

Changed January 25, 2008 07:59PM UTC by bmsterling comment:3

This works:

$('<div>').appendTo('body').hide().text('hi');

Changed March 20, 2008 04:23PM UTC by emartin24 comment:4

Is there a fix that can be applied to jQuery for this, or is it just up to the developer to know about it and use a workaround?

If I do a append, then hide, there is the potential of a visible 'flicker' since the element will be displayed, then hidden.

Otherwise, as mentioned above, adding a direct css of display: 'none' will work and avoid the possible 'flicker'.

The third option being a way for jQuery to handle it so that we are abstracted from this Safari issue. This would be ideal since it would make hide() consistent across all browsers.

Thoughts?

Changed March 20, 2008 04:49PM UTC by emartin24 comment:5

It looks like the failure is happening on:

jQuery.css(a,"display")!="none"

which is returning false.

What about something as simple as adding a browser sniff (for lack of a better idea ;) ):

($.browser.safari||jQuery.css(a,"display")!="none")

selector.js:

  • visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},

+ visible: function(a){return "hidden"!=a.type&&($.browser.safari||jQuery.css(a,"display")!="none")&&jQuery.css(a,"visibility")!="hidden";},

Changed March 20, 2008 09:38PM UTC by emartin24 comment:6

Well, I've been looking at it more and it looks like the issue comes from core.js (891-906):

// Go through and make them visible, but in reverse
// (It would be better if we knew the exact display type that they had)
for ( var i = 0; i < stack.length; i++ )
	if ( color( stack[ i ] ) ) {
	alert(stack[ i ].style.display);
		swap[ i ] = stack[ i ].style.display;
		stack[ i ].style.display = "block";
	}

// Since we flip the display style, we have to handle that
// one special, otherwise get the value
ret = name == "display" && swap[ stack.length - 1 ] != null ?
	"none" :
	( getComputedStyle && getComputedStyle.getPropertyValue( name ) ) || "";

// Finally, revert the display styles back
for ( var i = 0; i < swap.length; i++ )
	if ( swap[ i ] != null )
		stack[ i ].style.display = swap[ i ];

I haven't gone through it yet to see if a fix is possible, but it seems to be where the root of the issue comes from.

Changed September 19, 2008 12:12AM UTC by codeword comment:7

I am having this problem as well.

We are using closures in an object mother to build out our html for testing and it is not possible to wait until the elements are attached the dom before manipulating them.

I can use the '<div style="display:none;">' approach however.

Changed December 19, 2008 06:12PM UTC by john comment:8

milestone: 1.2.31.3
resolution: → duplicate
status: newclosed
version: 1.2.21.2.6

Duplicate of #1239.