Building Better jQuery DOM Inserts
Thursday, 20th December 2012, 15:18
So, write, you have some HTML that you need to insert into the DOM, how do you do it? Well, there are a couple of slightly different approaches for jQuery users, perhaps a common one is a simple string based approach like the following:
$("#myarea").html("<div><h1>A Great Big Giant Heading</h1><p>Some paragraph text which refers to <span id='animal'>dogs</span> like <span id='name'>Minna</span></div>");
But this is quite messy, sure it's fine for changing or inserting some text, but what if you might want to do something a bit more complicated with that text after you've inserted it?
Well you use some jQuery objects for them after the fact, like this:
$("#myarea h1").html("An even bigger heading!");
$("#animal").html("cat");
$("#name").html("Sirius");
$("#myarea p a").click(function() {
alert("Well yeah!");
});
But supposing at some point down the road you wanted to move this DIV you added? Or maybe remove it temporarily from the DOM and re-insert it later? Maybe you have a funky dialog box that pops up, and everytime it pops up you have to re-insert it, then set all the event binding up again.
A much more flexible way of doing the whole thing is like this:
var hdTitle = $("<h1>A Great Big Giant Heading</h1>");
var txAnimal = $("<span id='animal'>dogs</span>");
var txName = $("<span id='name'>Minna</span>");
var paInfo = $("<p>Some paragraph text which refers to ", txAnimal, " like ", txName, "</p>");
var btClickMe = $("<a href='#'>Click Me!</a>");
var paButtons = $("<p></p>");
paButtons.append(btClickMe);
var dvOuter = $("<div></div>");
dvOuter.append(hdTitle, paInfo, paButtons);
$("#myarea").append(dvOuter);
At first glance, that is a bit more typing, but it offers more possibilities. Because you've already assigned variables to jQuery objects, you can do some interesting things. Obviously we can now do this instead of our first example:
hdTitle.text("An even bigger heading!");
txAnimal.text("cat");
txName.text("Sirius");
btClickMe.click(function() {
alert("Well yeah!");
});
Now, supposing we suddenly have to make it so our dialog can appear multiple times, clearly we have to change every ID to a class. But because we only name the element once, at the same time we assign it to a variable, we don't have to worry at all about searching our Javascript, which may be across many files, to find all the places we reference it.
Also, we can change the function of our button like this:
var btDontClickMe = $("<a href='#'>Whatever You Do Don't Click Me!</a>");
btDontClickMe.click(function() {
alert("Well I did say?");
});
paButtons.html(btDontClickMe);
And then we can swap it back like this:
paButtons.html(btClickMe);
See! We don't even have to rebind the click event because the old one still exists even though it got replaced.
In fact this approach is better for other reasons, it seperates to a certain extent the code from the HTML it works on. That lets you change the HTML later on without having to worry as much about its affect on the underlying code.
I try to take this approach whenever matters allow, as breaking down things this way makes them much more manageable and flexible in the long run. Not to mention being more efficient when it comes to saving on DOM lookups. Now I know, some of you kids out there will go on about how computers are more powerful today so who cares if you work the CPU 0.5% harder by being lazy?
Thinking like that gave us Windows. I hate BASIC with a passion, but Bob Zale, author of PowerBASIC had it right when he plastered a mantra on his office walls:
Unless something makes code harder to read and maintain, then this is what every good coder should be thinking.