I've been running my head into a wall trying to figure this out. Take the following HTML body:
<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()
portion 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 just one of the two headings (if you remove the <h1>
or <h2>
from the HTML, the script runs successfully. Why is this?
To try for yourself, see http://jsbin.com/avisi/edit
Edit: I'm not actually trying to remove and element from the DOM and re-insert it by copying the HTML. This is just a test case for an error I'm having in more complex code, and I'm trying to understand why this error occurs. I agree that, if I wanted to accomplish just what is shown here, I would use something like $('#project').remove().children().appendTo('body')
By using show( ) and hide( ) methods you can show and hide HTML elements in jQuery.
The hide() is an inbuilt method in jQuery used to hide the selected element. Syntax: $(selector).
The jQuery hide() method is used to hide the selected elements. Syntax: $(selector). hide();
hide() sets the matched elements' CSS display property to none . remove() removes the matched elements from the DOM completely. detach() is like remove() , but keeps the stored data and events associated with the matched elements.
I cannot duplicate your error in Firefox. However, you might want to try cleaning it up with the following:
$('#project').remove().children().appendTo('body').hide();
Broken down, this is what's happening
// 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 are proposing that .hide()
is causing problems since the node that it is being applied to is not part of the main document; however, this is just not the case. As long as you maintain a reference to any node, you can affect its style property (via hide
, show
, etc).
One things you might want to check is to make sure that $('#project')
is actually returning the (if any) expected node. Problems may arise otherwise.
So I poked around 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 (the var
statement) has no return value (which it doesn't)
> 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's the error that you described. Inspecting each item in jQuery object will reveal the error below
> t[0]
<h1 style="display: none; ">Hi</h1>
Good...
> t[1]
(whitespace)
Dammit. Really? Here's the problem. whitespace nodes have no style
attribute, which is what's causing the problem.
> t[2]
<h2>Hello</h2>
This is why copying the HTML of one node to another just to move those nodes is a bad technique. I suggest you use the snippet that I provided above.
There's a text node being selected in the $(h). We can filter that out using the filter function though.
This should work (I've only tested in FF though):
$(function(){
var h = $('#project').html();
$('#project').remove();
$(h).filter("*").hide().appendTo('body');
alert("Created HTML, hide, and appended!");
});
Pretty wierd behaviour IMO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With