I need to get all children of a DIV and their children too. I mean I need to get the HTML text of a DIV but I don't like to use innerHTML since it does not support the values of inputs in many browsers. How can I do that? :-/

Dani AI

Generated

As noted, walking childNodes works for structure, but innerHTML often does not reflect the current runtime state of form controls (value/checked/selected). A reliable pattern is: clone the subtree, copy each form control's live state onto the clone (value, checked, selected, textarea text), then serialize the clone. The reverse is to parse the HTML string into a container and explicitly set element properties from attributes so control state matches the serialized state.

Example: serialize a DIV (returns inner HTML by default; pass true to include the DIV element itself)

function getHtmlWithValues(root, includeRoot) {
  includeRoot = !!includeRoot;
  var clone = root.cloneNode(true);
  var origControls = root.querySelectorAll('input,textarea,select');
  var cloneControls = clone.querySelectorAll('input,textarea,select');
  for (var i = 0; i < origControls.length; i++) {
    var o = origControls[i], c = cloneControls[i];
    if (!c) continue;
    var tag = o.tagName.toLowerCase();
    if (tag === 'textarea') {
      c.textContent = o.value;
    } else if (tag === 'select') {
      for (var j = 0; j < o.options.length; j++) {
        if (o.options[j].selected) c.options[j].setAttribute('selected', 'selected');
        else c.options[j].removeAttribute('selected');
      }
    } else {
      if (o.type === 'checkbox' || o.type === 'radio') {
        if (o.checked) c.setAttribute('checked', 'checked'); else c.removeAttribute('checked');
      }
      c.setAttribute('value', o.value);
    }
  }
  return includeRoot ? clone.outerHTML : clone.innerHTML;
}

Example: restore HTML into a container and reapply control state (preserves order):

function setHtmlWithValues(target, html) {
  target.innerHTML = html;
  var controls = target.querySelectorAll('input,textarea,select');
  for (var i = 0; i < controls.length; i++) {
    var e = controls[i], tag = e.tagName.toLowerCase();
    if (tag === 'textarea') {
      e.value = e.textContent || e.innerHTML || e.value;
    } else if (tag === 'select') {
      for (var j = 0; j < e.options.length; j++) {
        e.options[j].selected = e.options[j].hasAttribute('selected');
      }
    } else {
      if (e.type === 'checkbox' || e.type === 'radio') e.checked = e.hasAttribute('checked');
      var v = e.getAttribute('value');
      if (v !== null) e.value = v;
    }
  }
}

Notes and caveats:

  • Event listeners are not cloned; use event delegation or reattach listeners after insertion.
  • Mapping clone controls by index assumes the cloned structure matches the original. If the DOM may differ, tag nodes with a temporary data-id before cloning and match by that.
  • Inserting untrusted HTML is an XSS risk; prefer serializing only form data (JSON/FormData) when only values are needed.
  • For inserting element-by-element while keeping order, parse into a temporary container and move children into a DocumentFragment before appending to the target.

This approach answers ’s follow-up about the reverse action and avoids innerHTML’s shortcomings for form control state.

Recommended Answers

All 2 Replies

I need to get all children of a DIV and their children too. I mean I need to get the HTML text of a DIV but I don't like to use innerHTML since it does not support the values of inputs in many browsers. How can I do that? :-/

<script language="JavaScript">
function test(){
var listOfChildNodes = document.getElementById('IDofTheDiv').childNodes;
var numberOfChildNodes = listOfChildNodes.length;
var str="";
for(i=0;i<numberOfChildNodes;i++){
   str += listOfChildNodes[i].tagName+"\n";// this is the way you access childNodes ... tagName is just for example purpose.
}
alert(str);
}
</script>
<div id= "IDofTheDiv">
<span></span>
<p></p>
<a></a>
</div>
<a href="javascript:test()">Click Here</a>

This is NOT what you exactly want .... but hope this would be of your help.

Regards ...

Thanks:)
And how should I do the reverse action? I mean if I have a string which contains HTML tags, how can I add it to a DIV content element by element and in the same precedence?
:-/

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.