Our sign-in page for web apps currently uses javascript string concatenation to generate markup:
var signinHtml='<div>'+
' <form class="form-signin" method="post">'+
' <div class="form-signin-app-icon"></div>'+
' <h2 class="form-signin-heading">'+appName+'</h2> '+
' <h4 class="form-signin-heading-sub">'+appMotto+'</h4>'+
' <div class="form-signin-input">'+
' <input id="username" type="text" name="username" class="input-block-level" placeholder="Username"></input>'+
' </div>'+
' <div class="form-signin-input">'+
' <input type="password" name="password" id="password" class="input-block-level" placeholder="Password"></input>'+
' </div>'+
' <button class="btn btn-small btn-inverse form-signin-button" type="submit" id="signin">Sign in</button>'+
' </form>'+
'</div>';
$(self).html(signinHtml);
This approach works but is messy, error-prone, and probably not the best way of doing it. From what I've read, arrays are more efficient performance-wise but even worse in terms of readability. Can anyone remend a cleaner/better alternative?
Our sign-in page for web apps currently uses javascript string concatenation to generate markup:
var signinHtml='<div>'+
' <form class="form-signin" method="post">'+
' <div class="form-signin-app-icon"></div>'+
' <h2 class="form-signin-heading">'+appName+'</h2> '+
' <h4 class="form-signin-heading-sub">'+appMotto+'</h4>'+
' <div class="form-signin-input">'+
' <input id="username" type="text" name="username" class="input-block-level" placeholder="Username"></input>'+
' </div>'+
' <div class="form-signin-input">'+
' <input type="password" name="password" id="password" class="input-block-level" placeholder="Password"></input>'+
' </div>'+
' <button class="btn btn-small btn-inverse form-signin-button" type="submit" id="signin">Sign in</button>'+
' </form>'+
'</div>';
$(self).html(signinHtml);
This approach works but is messy, error-prone, and probably not the best way of doing it. From what I've read, arrays are more efficient performance-wise but even worse in terms of readability. Can anyone remend a cleaner/better alternative?
Share Improve this question asked Jul 31, 2014 at 13:54 user1985189user1985189 6696 gold badges16 silver badges26 bronze badges 4- 2 There are many ones, like having only one string (yes, you can have a multi-line string literal in JS), using jquery DOM functions, using a template, etc. – Denys Séguret Commented Jul 31, 2014 at 13:55
- And no arrays aren't more efficient, that's mostly urban legend based on old tests on old versions of some engines. – Denys Séguret Commented Jul 31, 2014 at 13:57
-
I use
document.createElement()
to create elements... jQuery has a way to do this as well, but it's slower (obviously) -- ($("<div>")
creates a div) – ndugger Commented Jul 31, 2014 at 14:02 - Concatenation is one of the things that recent optimizations in many browsers have focused on. Do not worry too much about performance of arrays versus strings; focus on readable code. – Joeppie Commented Jul 31, 2014 at 14:12
4 Answers
Reset to default 7I would suggest looking up template engines, such as Mustache or Handlebars.
Those would allow you to define your markup in a simple language that is then parsed by the template piler so that they're available in your Javascript, so that all you have to do is pass in your data and get HTML back.
EDIT: An example of how this could work with Handlebars (I'm using that because it's what I used last, but the concepts are the same regardless of what you use).
First you create a template. The template is just your HTML, but you represent your data with tokens. It could look like this:
<div>
<h1>My name is {{ name }}</h1>
<p>Here's some information about me: {{ about }}</p>
</div>
That template has to be accessed somehow in your Javascript. The simplest way to do that is to simply put it in a script tag with a certain type:
<script id="my-template" type="text/x-handlebars-template">OUR TEMPLATE GOES HERE</script>
Then we have to pile the template. What that means is that the template engine takes the HTML-like text that we created, parses that and turns it into a javascript function. In handlebars, that is done like this:
var template = Handlebars.pile($('#my-template').html());
(Note that in this example I'm using jQuery to get the contents of the script tag)
template
is now a Javascript function that will return HTML if I supply it with the data we need (name
and about
). So let's do that:
var data = {name: 'Tommy Brunn', about: 'I like cats and Belgian beer'};
var output = template(data);
output
will now contain the HTML from our template, but with the tokens replaced with my data:
<div>
<h1>My name is Tommy Brunn</h1>
<p>Here's some information about me: I like cats and Belgian beer</p>
</div>
This is just the simplest example of a template. Some templating languages allow you to do things like loop over lists, modify variables (for example, uppercasing) or perform selections ("if name
is more than 5 letters long, reverse it").
In this example, the pilation of the template is done on the client side. That's fine in most cases, but if you need the extra performance, you probably want to do the pilation on the server side. Most (maybe all?) template engines provide you with a way to do that as part of your build process. What you'd end up with then is a Javascript file that contains the function that your template piled to. Another benefit of that is that you won't need to include the full piler on your site. You only need a smaller runtime instead.
The best answer to the question has already been provided by Tommy Brunn above, however, there is a solution for if you are dealing with small snippets.
var element = $("<a />", {"href": "http://www.example.", "target": "_blank", "class": "example-class"}).html("example.");
parent.append(element);
It is particularly useful if you need to create elements that have a lot of dynamic attributes and require attached events and other interactions. I find it much cleaner than strings of text and then searching (.find()) through them after the fact to find elements.
USE TEMPLATE LITERALS
your code looks like this which use '+' several times and it looks ugly.
var a = 5;
var b = 10;
console.log('Fifteen is ' + (a + b) + ' and\nnot ' + (2 * a + b) + '.');
// "Fifteen is 15 and
// not 20."
How if i write code like this
var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b} and
not ${2 * a + b}.`);
// "Fifteen is 15 and
// not 20."
All the latest browser except Safari , IE supporting template literals
Angularjs also supplies some good template mechanisms, if you're looking for alternatives to those mentioned.