Handling HTML element contents: innerHTML vs cloneNode

Posted by admin at December 6, 2015

Working on JavaScript projects, you come across a lot of functions that require you getting a hold of the contents of a HTML element, and manipulating it in some way: performing a string search, splitting it up, concatenation, replacing a string in it or copy to another element. One of the most common ways of doing this is to get the innerHTML property of the element.

Syntax:

var html_content = div_id.innerHTML;

The variable, ‘html_element’ now contains the HTML contents of the element with the identifier ‘div’. So for instance, getting the contents of a div element such as ‘div_id’ below.


<div id="div_id">
    <bold>Heading:</bold>
    <br>The contents of the is div in <bold>bold</bold> or <em>italics</em>
</div>

would be


<bold>Heading:</bold> the contents of the is div in <bold>bold</bold> or <em>italics</em>

This is a string showing the contents of the div element. This string is ready for use.

Another way retrieve contents of a HTML element, would be to use the cloneNode option to duplicate the html element, including the inline contents (attributes and event listeners) of the HTML element tag and place it in a variable. The innerHTML property only copies

Syntax:

var clonedNode = node.cloneNode(deep);

where

node The node to be cloned.
clonedNode The new node that will be a clone of node
deep (Optional) true if the children of the node should also be cloned, or false to clone only the specified node.

So for our example, cloning the node would return a variable that contains an exact copy of ‘div_id’


<div id="div_id">
    <bold>Heading:</bold>
    <br>The contents of the is div in <bold>bold</bold> or <em>italics</em>
</div>

Note that this is NOT a string yet When a node is cloned, a copy of all the attributes and inline event listeners as well as child nodes are copied to a new variable. This variable or clone remains separate from the document until it is added with the Node.appendChild().

Major difference between the two:

Apart from the fact that cloneNode duplicates an target element node to be later added to the document where innerHTML is just pure string content of the target element in HTML code, the cloneNode serves a better function when creating elements or moving around elements with javascript. In specifications that require that elements be created or modified during run time, the cloneNode option produces better persistent results as against innerHTML. A major disadvantage of the innerHTML that I have noticed is that when the user has set values on form elements such as text boxes and select boxes, innerHTML will not be able transfer these values to new locations.

For example, lets take simple task of collecting some employment and bio data for a number of individuals and we want to start with a form that we can duplicate with javascript at the click of a button:


<h4>Personnel Records</h4>
<a href="javascript:make_new_form_ih(tmplid);">add new personnel</a>
<div style="display:none;">
<div id="tmplid" style="display:none;">
    <div name="rows">
    Name: <input id="" name="" value="">
    Gender: <select id="" name="" value="">
            <option value="0">--</option>
            <option value="1">Female</option>
            <option value="2">Male</option>
        </select>
        <label><input type="checkbox" id="" name=""> Employed</label>
    </div>
</div>
</div>
<form id="frmid">
</form>

Notice that the template form, identified as ‘tmpid’, has been put in a hidden container. I have added a link to create a new form by duplicating the hidden template form “tmpid” using the function make_new_form_ih(); as defined below:


function make_new_form_ih(ctrlid)
{
    // get the innerhtml string from the template control
    var ih = ctrlid.innerHTML;

    // append this string to the innerHTML of the data entry area
    frmid.innerHTML += ih;

}

The function above simply appends the contents of the data entry form with the contents of the hidden template form. This way, the user can loads several new data entry forms on the fly. The disadvantage here is that the entries on previous preloaded forms will be wiped off every time a new form is loaded. This is the defect of the innerHTML option as it manipulates just the string content and not the nodes and their attributes. A solution to this would be the following


function make_new_form_cn(ctrlid)
{
    // create a new div node to server a buffer container
    var bNode = document.createElement("div");

    // loop through all the child nodes of the template, append each to the buffer node
    for (i=0; i<ctrlid.childNodes.length; i++)
    {
        // clone the template control
        var cNode = ctrlid.childNodes[i].cloneNode(true);
        
        // append this node the buffer container
        bNode.appendChild(cNode);
    }

    // append this node to the data entry area
    frmid.appendChild(bNode);

}

This function simply clones and appends clones to the data entry form without reseting the entries already made by the user in the preloaded forms. What we did was to get the template node (the source), create a new buffer node, copy and paste all the child nodes of the template node into the buffer (cloneNode for copy, appendChild for paste) and append the buffer node to the data entry area.

Trying it out and putting it all together:

Personnel Records


clear forms [innerHTML] add new personnel [innerHTML] add new personnel [cloneNode]
Name: Gender:

Illustrations and extracts:


// using the innerHTML
destination.innerHTML = source.innerHTML;

// using the nodeClone
for (i=0; i<source.childNodes.length; i++)
{
    destination.appendChild(source.childNodes[i].cloneNode(true));
}

   0 likes

Tags: , , ,


Suggested Read