Generating HTML in JavaScript can be painful. It quickly gets out of control when building any advanced UI.

Let’s say we want to display a contact list using a list of contacts with this schema:

{
  name: 'Joe',
  img: '/pics/Joe.png',
  phone: '987-654-3210'
}

We want the resulting HTML to look like this:

<div class="contacts">
    <div class="contact">
        <img class="thumb" src="/pics/Joe.png" />
        <div class="name">Joe</div>
        <div class="phone">987-654-3210</div>
    </div>
    <!-- more contacts... -->
</div>

Vanilla JavaScript

Traditionally, with vanilla JS, we generated elements directly. jsFiddle

var list = document.createElement('div');
list.className = 'contacts';
for(var i = 0; i < contacts.length; i++){
    var contact = document.createElement('div');
    contact.className = 'contact';
    
    var img = document.createElement('img');
    img.src = 'http://lorempixel.com/50/50/people/' + contacts[i].name;
    img.className = 'thumb';
    contact.appendChild(img);
    
    var name = document.createElement('div');
    name.className = 'name';
    name.innerHTML = contacts[i].name;
    contact.appendChild(name);
    
    var phone = document.createElement('div');
    phone.className = 'phone';
    phone.innerHTML = contacts[i].phone;
    contact.appendChild(phone);
    
    list.appendChild(contact);
}
document.body.appendChild(list);

Using vanilla JS is a lot of work; 23 lines of code to generate our simple contact list. It’s also error prone because of cross-browser compatibility issues.

jQuery

jQuery, released in 2006, solved our browser compatibility issues and made DOM manipulation easier. jsFiddle

var list = $('<div>').addClass('contacts');
for(var i = 0; i < contacts.length; i++){
    var contact = $('<div>').addClass('contact');
    
    var img = $('<img>')
        .attr('src', 'http://lorempixel.com/50/50/people/' + contacts[i].name)
        .addClass('thumb')
        .appendTo(contact);
    
    var name = $('<div>')
        .addClass('name')
        .text(contacts[i].name)
        .appendTo(contact);
    
    var phone = $('<div>')
        .addClass('phone')
        .text(contacts[i].phone)
        .appendTo(contact);
    
    list.append(contact);
}
$(document.body).append(list);

This is about the same number of lines of code as vanilla JS, though there are many less characters which I say leads to enhanced readability. We also don’t have to worry about browser compatibility.

Handlebars

We can do better. Instead of building the HTML in JavaScript, let’s separate the HTML from the JavaScript in the same way we separate CSS from HTML. We’ll use Handlebars to create HTML templates which are later compiled and populated.

First, our HTML template is embedded in a script tag in our HTML page.

<script id="contacts-template" type="text/x-handlebars-template">
    <div class="contacts">
        {{#each contacts}}
        <div class="contact">
            <img class="thumb" src="http://lorempixel.com/50/50/people/{{name}}" />
            <div class="name">{{name}}</div>
            <div class="phone">{{phone}}</div>
        </div>
        {{/each}}
    </div>
</script>

Then in JavaScript we retrieve, compile, and evaluate our template. jsFiddle

var source = document.getElementById('contacts-template').innerHTML;
var template = Handlebars.compile(source);
document.body.innerHTML = template(data);

That is much better. Our HTML is in a template which makes refactoring the HTML much easier (imagine trying to refactor the HTML construction in the first two examples). We also get syntax highlighting for the HTML when in our IDE. And now our JavaScript has been reduced from 23 lines to 3 lines for this simple example (the savings can be much larger for more complex projects).

Checkout the jsFiddles for complete and working examples of the three usecases we presented here: vanilla JS, jQuery, and Handlebars.