cloneNode() - DOM Compliant Copying of "innerHTML / innerText"

for IE5+, Netscape 6+, Safari

I can no longer deny it - I'm a true geek; I'm crazy about the DOM's cloneNode() method.

cloneNode() is the DOM equivilent of using "innerHTML" or "innerText" to copy existing nodes. If you're interested in the DOM compliant way to create new "innerHTML" or "innerText", click here

cloneNode() has 2 parameters: true and false.
x.cloneNode(true) makes a copy of x, all it's attributes, and all it's subnodes.
x.cloneNode(false) copies only the x node and it's attributes.

Let's look at how the method works using the two parameters. We'll copy the div id="cloneMe" and put it into div id="test1" using the appendChild() method.

<script>
function copyTrue(){
var t = document.getElementById('cloneMe').cloneNode(true);
document.getElementById('test1').appendChild(t);
}

function copyFalse(){
var f = document.getElementById('cloneMe').cloneNode(false);
document.getElementById('test1').appendChild(f);
}
</script>
This is div id="cloneMe".
<div id="test1">
</div>

Tell me that's not cool. cloneNode() provides the same functionality as "innerHTML" only with more power and flexability. You'll see what I mean in the next example.

_________________________________

Below are two tables. What we're going to do is clone the first row in the table on the left and append it to the table on the right. No attributes have been assigned to the rows, only the table elements, so the copy should look like all the other rows in table2. table1 contains a thead element. table2 does not.

<script>
function copyRow(){
 // - get the tbody of table id="table1"
 var tb = document.getElementById('table1').getElementsByTagName('tbody')[0]
 // - clone the first row of var tb
 var r = tb.getElementsByTagName('tr')[0].cloneNode(true);
	  
  // - append it to table id="table2"
  document.getElementById('table2').appendChild(r);
  
  // - Please note: you MUST include the tbody references for this to work!!
}
</script>
Table id="table1"
DistrictAddressZipPhone
6th Police District11th and Winter Streets19107(215) 686-3060
Table id="table2"
1st Police District24th and Wolf Streets19145(215) 686-3010
2nd Police DistrictHarbison Avenue and Levick Street19149(215) 686-3150
3rd Police District11th and Wharton Streets19147(215) 686-3030
4th Police District11th and Wharton Streets19147(215) 686-3040
5th Police DistrictRidge Avenue and Cinnaminson Street19128(215) 686-3050

 

Try doing THAT with "innerHTML"!

_________________________________


There's one other important use of cloneNode() we should cover and that's using it in conjunction with createElement().

Let's say we want to create and append 5 text inputs to form name="testForm". One way to do it is like this -

  var firstName=document.createElement('input');
  firstName.setAttribute('type','text');
  firstName.setAttribute('name','FIRST');
  firstName.setAttribute('value','');
  firstName.setAttribute('size','15');
  firstName.style.backgroundColor='#ccf';
  firstName.style.border='1px #fff solid';	
  firstName.style.marginBottom='10px';
  
  var lastName=document.createElement('input');
  lastName.setAttribute('type','text');
  lastName.setAttribute('name','LAST');
  lastName.setAttribute('value','');
  lastName.setAttribute('size','15');
  lastName.style.backgroundColor='#ccf';
  lastName.style.border='1px #fff solid';
  lastName.style.marginBottom='10px';
  
  // -  etc. ... for three more inputs

But that's a lot of repeated code. Since the only differences between them are the 'name' and 'value' attributes, a more efficient way to write it is -

function addInputs(){

  // -  create a generic text input
  var textInput=document.createElement('input');
  textInput.setAttribute('type','text');
  textInput.setAttribute('size','15');
  textInput.style.backgroundColor='#ccf';
  textInput.style.border='1px #fff solid';	
  textInput.style.marginBottom='10px';

  // -  now create the individual text inputs by cloning testInput
  // -  and set the 'name' and 'value' attributes
  // -  remember, cloning will keep all the attributes you assigned to the generic
  var firstName=textInput.cloneNode(false);
  firstName.setAttribute('name','FIRST');
  firstName.setAttribute('value','first name');
  
  var lastName=textInput.cloneNode(false);
  lastName.setAttribute('name','LAST');
  lastName.setAttribute('value','last name');
  
  var city=textInput.cloneNode(false);
  city.setAttribute('name','CITY');
  city.setAttribute('value','city');
  
  var state=textInput.cloneNode(false);
  state.setAttribute('name','STATE');
  state.setAttribute('value','state');
  
  var zip=textInput.cloneNode(false);
  zip.setAttribute('name','ZIP');
  zip.setAttribute('value','zip');
  
  var f=document.forms['testForm'];
  f.appendChild(firstName);
  f.appendChild(document.createElement('br'));
  f.appendChild(lastName);
  f.appendChild(document.createElement('br'));
  f.appendChild(city);
  f.appendChild(document.createElement('br'));
  f.appendChild(state);
  f.appendChild(document.createElement('br'));
  f.appendChild(zip);
}
<form name="testForm">
</form>

Click here to add inputs to form name="testForm".

! This example will NOT work with IE5+ for Mac








PXL8 2003