Fork me on GitHub

James Allardice

Assorted thoughts of a web developer


James Allardice

I'm a young, enthusiastic web developer with a passion for front-end development with HTML5, JavaScript and jQuery. I spend a lot of my free time over at Stack Overflow where I enjoy helping out others with problems relating to the above technologies. I doubt I'll post here all the time, but I will try my best to ensure the things I do post are useful and interesting to anyone who may stumble across them!

I'm always on the lookout for exciting opportunities so if you have something that you think qualifies as such don't hesitate to get in touch.

Passing an element or object to the jQuery .html() method

Earlier today I answered a question on Stack Overflow. The question asked if there was a way to keep the original DOM element when inserting an existing element into another with the jQuery .html() method.

I answered, pointing out that by inserting an existing element into another, the element was effectively moved. My answer indicated the use of the .clone() method, which would allow you to create a copy of the element to insert, thereby leaving the original just where it was.

However, after answering the question I noticed in the jQuery documentation that only three signatures for the .html() method are listed:

//Get the HTML contents of the first element in the set of matched elements.

//Set the HTML contents of each element in the set of matched elements.
.html( htmlString )
.html( function(index, oldhtml) )

The first signature listed above is for retrieving the HTML contents of an element, so we can ignore that as that’s not related to what we are doing here. The next two signatures are for setting the HTML. Notice how neither signature specifies an element or a jQuery object as an argument. So how is it possible that we are able to do this:

var myElement = $("#someElement");

In the above snippet we get a reference to an element with the ID "someElement", and we insert that element into an element with the ID "anotherElement". According to the jQuery documentation this shouldn’t be possible. My first thought was that the object simply gets converted to a string, but jQuery doesn’t override the .toString() method so that’s no good. So a quick look at the jQuery source clears everything up:

if ( typeof value === "string" /* ... */ ) {
    //We end up here if we pass in a string
    try {
    // If using innerHTML throws an exception, use the fallback method
    } catch(e) {}
if ( elem ) {
    this.empty().append( value ); //In our case we end up here

So, if you don’t pass in a string, or if an exception is thrown during the "value is a string" branch, the .html() method falls back to using .append(). And the documentation for .append() helpfully points out:

If an element [...] is inserted elsewhere, it will be moved into the target (not cloned).

So that explains the behaviour detailed in the Stack Overflow question, and it also reveals a nice "hidden" use for the jQuery .html() method.

comments powered by Disqus


Latest Tweets

Copyright © 2012 James Allardice