Jump to main content
Menu

Creating, Inserting, and Removing Nodes

document.createElement()

  • This DOM method is always called from document and creates the indicated element node in memory.
  • The element node then needs to be inserted into the document, using methods covered later in this article.
  • Inserting an element node into the DOM causes a chain reaction in which various dynamic/live node lists (either ones you have created or ones the browser creates) are updated and the screen is redrawn.
    • This impacts performance, so ideally you should create everything you need in memory, specify attribute nodes / properties as necessary, and then insert that into the page.
    • That is preferable to incrementally inserting nodes into the DOM, which forces multiple screen redraws and recalculations.
    • Typically you create the element node for the outer tag (for example, a container <div></div>), add a variety of child nodes to that, and then insert the outer element node into the DOM. Everything inside of it comes along too.
  • Once the element has been inserted into the DOM it is still possible to adjust its attributes / properties, as long as there is a variable referencing the node. Or, if you lack such a reference, you can use the DOM selection methods to build a new reference to the node.
  • Code example for creating a paragraph element node in memory:
    const para = document.createElement('p');
    
  • Of course, we could have named this variable whatever we wanted, within the confines of the naming rules and the Reserved Words.
  • The document.createElement() method will work in XML as well.

document.createTextNode()

  • This DOM method is also always called from document and creates a text node with the indicated text in it.
  • Expanding upon the document.createElement() example:
    const para = document.createElement('p');
    const txt = document.createTextNode('Some sample text');
    
  • We now have:
    • A paragraph element node in memory
    • A text node in memory with a data / nodeValue of: Some sample text
  • The document.createTextNode() method will not convert HTML special characters (such as &middot;) unless they are specified using their Unicode values.

    The values in that linked Unicode document need a bit of massaging, since the value given (such as U+2026 for the ellipse) needs to use the escaped version which is \u2026.

    Modifying the previous code we have:

    const para = document.createElement('p');
    const txt = document.createTextNode('Some sample text \u2026');
    

appendChild()

  • This DOM method inserts element nodes and text nodes as the last child of the indicated element node.
  • There are some important considerations to keep in mind when appending nodes:
    • Self-terminated element nodes (such as <br />) cannot have child nodes appended; the child node has nowhere to go because self-terminated element nodes cannot have children (they are not containers).
    • Text nodes cannot have child nodes, so trying to insert any node as a child of a text node will fail.

appendChild() Example

See the Pen appendChild by Jason Withrow (@jwithrow) on CodePen.

Considerations with the appendChild() Example

  • There are two ways that we can insert an element node or text code. Either we assign it to a variable / property and insert that variable / property, or we create it on the fly within appendChild().
    • The first approach is good if we need to access that element node or text node later, because we have a reference to it.
    • The second approach reduces the variables we are creating and requires less code.
  • When generating and inserting lots of nodes use a for loop (or one of the other loop options) and array(s) holding the text node values.

appendData()

  • This DOM method appends text to the end of a text node.
  • As you have noticed, whenever append is part of the method name, you are putting whatever is appended at the end of the node content.
  • The mention of Data in a DOM method means that it is applied to a text node.
  • There are also non-DOM methods for String objects that allow us to edit text; those methods are part of the JavaScript language.

appendData() Example

See the Pen appendData by Jason Withrow (@jwithrow) on CodePen.

insertData()

  • This DOM method allows you to specify where you want text to be inserted into a text node.
  • When a method has insert in its name you can choose where the insertion will happen.
  • This method is passed two parameters:
    1. The first parameter is the numerical position where you are inserting the text.
    2. The second parameter is the text to insert, which needs to be quoted because it is a string.
  • Some things to keep in mind about strings:
    • Every string has a length property that reflects how many characters are in that string.
    • Each character in a string has a numerical position, with the first character at position 0 (just like an array, node list, and HTML collection).

insertData() Example

See the Pen insertData by Jason Withrow (@jwithrow) on CodePen.

insertBefore()

  • This DOM method allows you to insert an element node or text node before another element or text node.
  • The method must be called from the parent node and is passed two parameters:
    1. The first parameter is a reference to the node you are inserting.
    2. The second parameter is a reference to the node that the first parameter will precede.

insertBefore() Example

See the Pen insertBefore by Jason Withrow (@jwithrow) on CodePen.

insertAdjacentElement(), insertAdjacentHTML(), and insertAdjacentText()

  • These DOM methods are used for inserting an element (an element node created via JavaScript), some HTML (a string containing markup), or some text (a string), respectively.
  • They are called from an element node and accept two parameters.
  • The first parameter is the position/location where the insert occurs, and the second parameter is what is inserted.
  • The values for the first parameter are:
    • 'beforebegin': Before the element calling the method.
    • 'afterbegin': Inside the element, before its first child.
    • 'beforeend': Inside the element, after its last child.
    • 'afterend': After the element calling the method.
  • Some sample code:
    const el = document.querySelector('#main');
    el.insertAdjacentHTML('beforeend', '<footer id="ftr">Copyright text</footer>');
    
  • If insertAdjacentHTML() and insertAdjacentText() are used and you need to track down some of the added markup/text, you'll need to use the selection-related DOM methods after the insertion to find the desired nodes.

cloneNode()

  • This DOM method creates a copy of the indicated node.
  • It accepts a single parameter, set to either true or false.
    • true copies all the child nodes
    • false copies only the root node (the specific one you targeted)

cloneNode() Example

See the Pen cloneNode by Jason Withrow (@jwithrow) on CodePen.

removeAttribute()

  • This DOM method removes the indicated attribute.
  • An alternative to this method, if browser issues arise, is to simply set the attribute value to be "" or '', which has the same effect on the browser rendering in most cases.
  • If you are dealing with attributes that do not have a value (e.g., selected, checked, hidden, disabled, etc.) then using this method will be necessary (or you can use dot notation and set the property to false).
  • If we had acquired a <tr> element node (the reference to the node is theRow) that had an id specified, we could remove the attribute using:
    theRow.removeAttribute('id');
    

removeChild()

  • This DOM method removes the indicated child node (either a text node or element node).
  • If assigned to a variable, the removed node can then be inserted elsewhere in the DOM using appendChild(), insertBefore(), etc.
  • It does not need to be assigned to a variable, especially if you do not intend to re-use the removed node elsewhere in the document.
  • This is always called as a method of the parent element node that contains the child node to be removed.
  • Building upon the removeAttribute() example, if we wanted to remove a <td> within theRow, we could use:
    const theCell = theRow.getElementsByTagName('td')[0];
    const removedCell = theRow.removeChild(theCell);
    

    or reduce the code down to:

    theRow.removeChild(theRow.getElementsByTagName('td')[0]);
    
  • There is also a remove() method that can be called from the child node being removed.

deleteData()

  • This DOM method removes characters from a text node.
  • The method is passed two parameters, both of which are numbers:
    1. The first parameter is the character position where deletion begins (the character at that position is the first to be deleted).
    2. The second parameter is the number of characters to delete from that earlier point, moving from left to right through the string.

deleteData() Example

See the Pen deleteData by Jason Withrow (@jwithrow) on CodePen.

replaceChild()

  • This DOM method replaces an existing node with another node.
  • If the node you are swapping in already exists elsewhere in the DOM, it is removed from that other location.
  • The format is:
    theParentNode.replaceChild(childNodeToSwapIn,childNodeBeingReplaced)
    
  • In the above code, you create the node references for theParentNode, childNodeToSwapIn, and childNodeBeingReplaced.
  • If the above code is assigned to a variable, the childNodeBeingReplaced node is returned.

replaceData()

  • This DOM method needs three parameters passed:
    1. The first parameter is the character position where replacement begins; it is a number.
    2. The second parameter is a number reflecting the amount of characters being replaced.
    3. The third parameter is a string containing the text to swap in. This can be more or less characters than what was replaced.

replaceData() Example

See the Pen replaceData by Jason Withrow (@jwithrow) on CodePen.

Direct Modification of data or nodeValue Properties and normalize()

  • Every text node also has data and nodeValue properties that allow read access and write access to the content of the text node.
  • The two properties are aliases for each other; they work the same way.
  • It often comes as a surprise that creating a reference to a text node does not give direct access to the content of that node; an additional property needs to be accessed.
  • Consider the following code:
    <p>Hello world!</p>
    

    which we could tweak via either of these lines:

    referenceToParagraph.firstChild.data = 'Hello everybody!';
    referenceToParagraph.firstChild.nodeValue = 'Hello everybody!';
    
  • Only one of the two (data or nodeValue) is used; not both.
  • You may prefer to directly manipulate text node content via these properties rather than use one of the methods covered previously.
  • The normalize() method merges all the adjacent text nodes within an element node together and eliminates any empty text nodes, which is helpful if you've been inserting a series of text nodes and want to be able to access all of them as one.
  • Sample code:
    referenceToElement.normalize();
    

innerHTML

  • This began as a proprietary (non-standard) element node property introduced by Microsoft and has since been standardized.
  • This property allows the content within the element node to be treated as a readable / writable string.
  • Why do people like it?
    • You can read and write the tags and text within an element node easily, because that information is treated as a string and not as a series of nodes.
    • You can quickly delete the content within a node. A simple selectedElementNode.innerHTML = ''; and the inner code is gone. The equivalent in the DOM would be removing an element node that contains everything you want removed.
    • Special characters / entities do not need to use their Unicode value; they can be specified by name (e.g., &nbsp;) or number (e.g., &#160;).
    • Performance is faster than the DOM methods.
    • Less code is involved.
  • Why do people dislike it?
    • Nodes are treated as a text string, preventing you from being able to modify or access them easily. You have to write more code to isolate the desired element or part of the text after innerHTML has spewed out the code.
    • Functions as a sledgehammer rather than a surgeon's scalpel:
      • This makes it impractical for tasks involving tweaks to a number of nodes in various places in the document.
      • What if you needed to modify the 5th table cell in a row with 10 cells? You would need to grab the innerHTML of its <tr> but then you have a long string of all the cells. It's a mess.
    • Allows you to insert invalid HTML code, with no safeguards in place. DOM methods create valid code.
    • If you take user input and then kick it back out into the page via innerHTML a hacker could have you output a <script></script> tag loading a file from their server; the browser would view this as a trusted source since your page called the code.

innerHTML Example

See the Pen innerHTML by Jason Withrow (@jwithrow) on CodePen.

textContent and innerText

  • The textContent property of a node gets and sets all the text within the element, including its descendants. This offers a way to get all the text from a series of tags, and is very useful when doing things like filtering a table or list.
  • Using textContent to set content is very destructive, as it will eradicate all the markup and replace it with a single text node.
  • innerText is similar but only returns text for elements that are "human readable", so hidden elements, script tags, and style tags are all skipped. In contrast, textContent looks at all of those. Setting text via innerText is similarly destructive.
  • textContent is faster to execute than innerHTML because the result is not parsed as HTML. There are also no concerns about cross-site scripting from user input being output to the browser, because all that would output are text nodes and not element nodes.