Ryan Elkins Ryan Elkins - 16 days ago 5
HTML Question

jQuery - Best Practice for creating complex HTML Fragments

Is there a general best practice for creating somewhat complex HTML elements in jQuery? I've tried a few different ways.

First I tried using createElement and chaining alot of those together with AppendTo and the like:

var badge = $(document.createElement("div")).attr("class", "wrapper1").appendTo("body");
$(document.createElement("div")).attr("class", "wrapper2").appendTo(".wrapper1");
$(document.createElement("table")).attr("class", "badgeBody").appendTo(".wrapper2");
$(document.createElement("tr")).attr("class", "row1").appendTo(".badgeBody");
$(document.createElement("span")).attr("class", "badgeUnlocked").text("UNLOCKED! ").appendTo("td");
$(document.createElement("td")).attr("class", "badgeTitleText").appendTo(".row1");
$(document.createElement("span")).attr("class", "badgeTitle").text(name).appendTo(".badgeTitleText");
$(document.createElement("tr")).attr("class", "row2").appendTo(".badgeBody");
$(document.createElement("img")).attr("src", imgUrl).appendTo(".row2 td");
$(document.createElement("td")).attr("class", "badgeText").appendTo(".row2");
$(document.createElement("span")).attr("class", "badgeDescription").text(description).appendTo(".badgeText");

This can be rough since appendTo wants to add to every matching element so everything needs its own name otherwise it ends up getting added repeatedly all over the place.

Then I tried creating an array and joining it together:

var badgeFragment = [
'<div><div id="'+ closeId+'" class="closeTab">X</div>',
'<div id="'+ badgeId+'" class="wrapper1">',
'<div class="wrapper2">',
'<div class="badgeBody">',
'<div class="badgeImage">',
'<img src="'+ imgUrl +'">',
'<div class="badgeContents">',
'<div class="badgeUnlocked">ACHIEVEMENT UNLOCKED: </div>',
'<div class="badgeTitle">'+ name +'</div>',
'<div id="'+ textId+'" class="badgeDescription">'+ description +'</div>',
'<div style="clear:both"></div>',

badgeFragment = $(badgeFragment.join(''));

This seems to work pretty well, although in IE when I would put an alert($(badgeFragment).text()) it usually came back empty. (This was part of debugging a larger problem). I'm obviously a bit new to jQuery (And even Javascript really) so to try and make sure this wasn't the problem I tried a third method - giant string concatenation:

var badgeFragment =
'<div><div id="'+ closeId+'" class="closeTab">X</div>' +
'<div id="'+ badgeId+'" class="wrapper1">' +
'<div class="wrapper2">' +
'<div class="badgeBody">' +
'<div class="badgeImage">' +
'<img src="C:/Users/Ryan/Documents/icons/crystal_project/64x64/apps/chat.png">' +
'</div>' +
'<div class="badgeContents">' +
'<div class="badgeUnlocked">ACHIEVEMENT UNLOCKED: </div>' +
'<div class="badgeTitle">test</div>' +
'<div id="'+ textId+'" class="badgeDescription">test</div>' +
'</div>' +
'<div style="clear:both"></div>' +

Is one of these methods generally considered better than the others? I'm not really good with the various profilers so I'm not sure how to verify this myself. There is also the question of how whether or not all of these methods are cross browser compliant.


With jQuery 1.4, you can create HTML elements like so:

// create an element with an object literal, defining properties
var e = $("<a />", {
    href: "#",
    "class": "a-class another-class", // you need to quote "class" since it's a reserved keyword
    title: "..."

// add the element to the body

Here's a link to the documentation.

I'm not sure that this approach is faster than using the html() function of jQuery. Or faster than skipping jQuery all together and use the innerHTML property on an element. But as far as readability goes; the jQuery-approach is my favorite. And in most cases the performance-gain of using innerHTML is marginal.