Bug Tracker

Ticket #2233 (closed bug: duplicate)

Opened 7 years ago

Last modified 3 years ago

.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:
Blocking: Blocked by:

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') )

Change History

comment:1 Changed 7 years ago by tmm1

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

comment:2 Changed 7 years ago by davidserduke

This should work too:

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

comment:3 Changed 7 years ago by bmsterling

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

comment:4 Changed 7 years ago by emartin24

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?

comment:5 Changed 7 years ago by emartin24

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";},

comment:6 Changed 7 years ago by emartin24

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.

comment:7 Changed 6 years ago by codeword

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.

comment:8 Changed 6 years ago by john

  • Status changed from new to closed
  • Version changed from 1.2.2 to 1.2.6
  • Resolution set to duplicate
  • Milestone changed from 1.2.3 to 1.3

Duplicate of #1239.

Note: See TracTickets for help on using tickets.