brabec
brabec

Reputation: 4730

Shorten code to create DOM fragment using jQuery

I have the following code to create a tree of Element which I'm using as an input to JsTestDriver unit test. Could it be followed using jQuery? I looked into jQuery.parseHTML function, but I need to extract a DOM Element eventually.

var doc = document.implementation.createHTMLDocument('');
var root = doc.createElement('DIV');
root.appendChild(doc.createTextNode('Web '));
var span1 = doc.createElement('SPAN');
span1.setAttribute("class", HL_CLASS);
span1.appendChild(doc.createTextNode('browsers'));
root.appendChild(span1);
root.appendChild(doc.createTextNode(' must '));
var span2 = doc.createElement('SPAN');
span2.setAttribute("class", HL_CLASS);
span2.appendChild(doc.createTextNode('die'));
root.appendChild(span2);
root.appendChild(doc.createTextNode(''));

Upvotes: 0

Views: 100

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1073968

It could be shorted dramatically without jQuery: After your second line, just assign a string containing HTML to root.innerHTML:

var doc = document.implementation.createHTMLDocument('');
var root = doc.createElement('DIV');
root.innerHTML =
    'Web <span class="' + HL_CLASS +
    '">browsers</span> must <span class="' + HL_CLASS +
    '">die</span>';

With jQuery, you can do much the same thing with the $() function, which accepts strings containing HTML fragments and creates the DOM elements for them (and stores the top level elements in the jQuery object it returns).

var doc = document.implementation.createHTMLDocument('');
var root = $(
    '<div>' +
    'Web <span class="' + HL_CLASS +
    '">browsers</span> must <span class="' + HL_CLASS +
    '">die</span>' +
    '</div>',
    doc)[0];

Note that with the jQuery version, I had to pass your custom-built document as the second argument.

Both of those could be made a bit clearer with a bit of simple templating (and there are many templating implementations to choose from). Here's a very, very basic example without any templating engine, just to show the benefit:

var doc = document.implementation.createHTMLDocument('');
var html = 
    '<div>' +
    'Web <span class="{HL_CLASS}">browsers</span> ' +
    'must <span class="{HL_CLASS}">die</span>' +
    '</div>';
var root = $(html.replace(/\{HL_CLASS\}/g, HL_CLASS), doc)[0];

Ideally, though, you'd load that template dynamically from a file where you can edit it properly (using a build tool to embed it for production), rather than string literals.

Upvotes: 2

Santiago Rebella
Santiago Rebella

Reputation: 2449

something like that:

var $dock = $('body'), $root = $('<div/>', { 'id' : 'adOverlay' }), 
    $container = $('<div/>', { 'id' : 'adContainer' }).appendTo($root),  
    $exterior = $('<div/>', { 'id' : 'adOutdoor' }).appendTo($container), 
    $interior = $('<div/>', { 'id' : 'adInterior' }).appendTo($container), 
    $retrovisor = $('<div/>', { 'id' : 'adRetrovisor' }).appendTo($interior), 
    $retrovisorInner = $('<div/>').appendTo($retrovisor), 
    $close = $('<div/>', { 'id' : 'adOverlayClose' }).append('<div>&times;</div>').appendTo($root);
    $root.appendTo($dock);

EDIT

I mean I think is a clean way to do it, but you could also use .html('<div>you html here</div>');

Upvotes: 0

Related Questions