How to substitute element contents with DOM-manipulation-functions in JavaScript?

css, dom, html, javascript

Solution

- Removing can be done more easily by using `element.innerHTML = '';`

- Generating content can also be done more easily be either adding the content using `.innerHTML`, or caching a collection of elements. or

- `elem.parentNode.replaceChild(new_elem, elem);` on the `#test` element will be the easiest way.

Using cached DOM elements

Demo: http://jsfiddle.net/aKASN/1/

HTML:

<input type="text" id="input">
<div id="test"></div>

JavaScript:

window.onload = function() {
    // References
    var limit_reached = document.createElement('div');
    limit_reached.id = 'test';
    limit_reached.innerHTML = 'You reached the maximum length';

    var chars_left = document.createElement('div');
    chars_left.id = 'test';
    chars_left.innerHTML = 'You have <em id="number_of_chars">30</em> characters left';

    document.getElementById('input').onkeyup = function() {
        var char_count = this.value.length;
        var limit = 20;
        var test = document.getElementById('test');

        if ( char_count > limit ) {
            test.parentNode.replaceChild(limit_reached, test);
        } else {
            chars_left.getElementsByTagName('em')[0].innerHTML = limit - char_count;
            test.parentNode.replaceChild(chars_left, test);
        }
    };
};

Using hidden elements (recommended)

Another method, which I recommend over the previous ones, is to have all elements in the and hide the unused messages using a CSS. This is more efficient than DOM manipulation, because the elements don't have to be created over and over again.

Demo: http://jsfiddle.net/aKASN/

CSS:

.hidden {display:none;}

HTML:

<input type="text" id="input">
<div><!-- Original id="test" -->
   <span id="charsleft" class="hidden">
      You have
      <em id="number_of_chars">30</em>
      characters left
   </span>
   <span id="limit_reached" class="hidden">
       You reached the maximum length
   </span>
</div>

JavaScript:

window.onload = function() {
    // References
    var chars_left = document.getElementById('charsleft');
    var number_of_chars = document.getElementById('number_of_chars');
    var limit_reached = document.getElementById('limit_reached');
    var input = document.getElementById('input');

    input.onkeyup = function() {
        // Example value:
        var char_count = input.value.length;

        // Example: 20 character limit
        if ( char_count > 20 ) {
            chars_left.className = 'hidden';
            limit_reached.className = '';
        } else {
            chars_left.className = '';
            number_of_chars.innerHTML = 20 - char_count;
            limit_reached.className = 'hidden';
        }
    };
};

Problem

I have a Element, that looks like this: ``` <div id="test"> <span>You have <em>30</em> <span> characters left</span> </div> ``` and I want to replace it either with: ``` <div id="test"> <span>You reached the maximum length</span> </div> ``` or with ``` <div id="test"> <span>Your text is </span> <em>30</em> <span> characters to long</span> </div> ``` Is there a way to replace all child elements with the set of new elements? At the Moment I'm using to following function to remove all elements first: ``` function emptyElement(id) { while(document.getElementById(id).hasChildNodes()) { document.getElementById(id).removeChild(document.getElementById(id).firstChild) } } ``` Afterwards I'm adding content again: ``` span1 = document.createElement("span"); span1.appendChild(document.createTextNode("You have ")); len = document.createElement("em"); len.appendChild(document.createTextNode(length)); span2 = document.createElement("span"); span2.appendChild(document.createTextNode(" characters left.")); // remove child elements emptyElement('test'); // Add content document.getElementById('test').appendChild(span1); document.getElementById('test').appendChild(len); document.getElementById('test').appendChild(span2); ``` I have the impression that there might be an easier way for (1) removing the child-elements, (2) generationg the content and (3) adding the new elemnts to the div.

Original source