Why can't jQuery hide specific HTML?
I ran my head against the wall, trying to figure it out. Take the following HTML:
<body> <div id="project"> <h1>Hi</h1> <h2>Hello</h2> </div> </body> And the following jQuery code:
$(function(){ var h = $('#project').html(); $('#project').remove(); $(h).hide().appendTo('body'); alert("Created HTML, hide, and appended!"); }); The $(h).hide() causes jQuery to throw an exception in Safari 4 and Firefox 3.5.
Safari: TypeError: Result of expression 'this[a].style' [undefined] is not an object.
Firefox: uncaught exception: [Exception... "Could not convert JavaScript argument arg 0" nsresult: ...]
When I change the HTML to contain only one of the two headers (if you remove <h1> or <h2> from the HTML, the script runs successfully. Why is this?
To try yourself, see http://jsbin.com/avisi/edit
Edit: I'm not really trying to remove the element from the DOM and paste it again by copying the HTML. This is just a test case of an error that I encountered in more complex code, and I'm trying to understand why this error occurs. I agree that if I wanted to do just what is shown here, I would use something like $('#project').remove().children().appendTo('body')
I cannot duplicate your error in Firefox. However, you can try to clean it like this:
$('#project').remove().children().appendTo('body').hide(); Broken is what happens
// Get the `project` container $('#project') // Remove it from the page .remove() // Get its children (the h1, h2, etc) .children() // Append those nodes to the body .appendTo('body') // Hide those nodes .hide(); Others suggest that .hide() cause problems, since the node to which it is applied is not part of the main document; however, this is simply not so. As long as you maintain a link to any node, you can influence its style property (via hide , show , etc.).
One thing you can check is to make sure $('#project') actually returns the expected (if any). Otherwise, problems may arise.
So, I poked in Safari and found your problem. Here's a dump from the developer console.
> var h = $('#project').html(); undefined > var t = $(h); undefined So far so good. undefined here simply means that the statement ( var statement) has no return value (which is not)
> t.hide() ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js:131TypeError: Result of expression 'this[a].style' [undefined] is not an object. Here is the error you described. Checking every item in a jQuery object will detect an error below
> t[0] <h1 style=โ"display:โ none;โ ">โHiโ</h1> Good...
> t[1] (whitespace) Damn it. Indeed? Here is the problem. space nodes do not have the style attribute, which causes the problem.
> t[2] <h2>โHelloโ</h2> This is why copying the HTML of one node to another in order to move these nodes is a bad technique. I suggest you use the snippet that I provided above.
In the text $ (h), the text node is selected. We can filter this using the filter function.
This should work (I tested only in FF):
$(function(){ var h = $('#project').html(); $('#project').remove(); $(h).filter("*").hide().appendTo('body'); alert("Created HTML, hide, and appended!"); }); Pretty weird IMO behavior.
You removed content from the DOM before, so there is nothing to hide. If you do
$(h).appendTo('body').hide(); he should work