views:

758

answers:

2

I have this code:

var $msg = jQuery('<div></div>')
    .hide()
    .appendTo(document.body)
;
if ($msg.is(":hidden")) {
    console.log("hidden");
} else {
    console.log("visible");
}

When run, it logs "hidden" on Firefox, but "visible" on Google Chrome. Is this a bug, or am I doing something wrong?

+3  A: 

Have you tried hiding after appending it to body?

$(function() {
    var $msg = jQuery('<div>hello</div>').appendTo(document.body).hide();
    if ($msg.is(":hidden")) {
        console.log("hidden");
    } else {
        console.log("visible");
    }
}); // $()

worked for me on both browsers.

eed3si9n
What does the outer $() do?
Beau Simensen
that's the shorthand form for the document.ready handler.
nickf
A: 

as eed3si9n said, it was that the .hide() call was before the .appendTo() call.

I thought I'd just add this answer as I found a different way which also works:

jQuery('<div></div>')
    .css("display", "none")
    .appendTo(document.body)
;

I don't know exactly if it works like this, but I imagine that adding the element to the DOM with it hidden should be quicker, since the browser doesn't need to render it?


An update for those of you who are like me and must know exactly how things work:

The code for jQuery.hide() - comments added by me

hide: function(speed,callback){
    return speed ?

        // this block of code won't be run, since speed will be undefined
        this.animate({
            height: "hide", width: "hide", opacity: "hide"
        }, speed, callback) :

        // this is the relevant code
        this.filter(":visible").each(function(){
            this.oldblock = this.oldblock || jQuery.css(this,"display");

            // you can see here that it merely sets the display to 'none'
            this.style.display = "none";
        }).end();
}

and here's the code for the :hidden selector:

hidden: function(a) {
    return "hidden" == a.type                        // <input type="hidden" />
        || jQuery.css(a, "display") == "none"        // style.display = none
        || jQuery.css(a, "visibility") == "hidden";  // style.visibility = hidden
}

This doesn't really explain why Chrome isn't showing the element as hidden though...

nickf
The browser shouldn't render your changes until the script finishes anyway, so I doubt it makes much difference in speed. Browsers can act strangely though, so anything is possible.
Matthew Crumley