W3docs

Node Properties: Type, Tag and Contents

Mastering the Document Object Model (DOM) is essential for any web developer looking to manipulate web pages dynamically. This article delves deep into the core

Every node in the DOM tree is a JavaScript object, and that object exposes properties that tell you what kind of node it is, what tag it represents, and what content it holds. Once you can read these properties confidently, navigating and editing a page becomes far less error-prone. This chapter covers the node class hierarchy, the type and name properties (nodeType, nodeName, tagName), and the four content properties you will reach for daily (textContent, innerHTML, outerHTML, and nodeValue/data) — including when each is safe to use.

If you have not yet seen how the DOM is structured as a tree, read Understanding the DOM Nodes first.

The node class hierarchy

DOM objects do not all share the same set of properties. They are arranged in a class hierarchy, where each class adds capabilities to the one above it:

  • Node — the base class. Every node (element, text, comment, document) inherits from it. It provides generic properties such as nodeType, nodeName, nodeValue, parentNode, and childNodes.
  • Element — a node that is a tag. Adds tagName, innerHTML, attributes, children, and query methods.
  • HTMLElement — the base for every concrete HTML element. Subclasses like HTMLInputElement, HTMLAnchorElement, and HTMLTableElement add tag-specific properties (e.g. input.value, a.href).
  • Text and Comment — leaf nodes that hold text. They inherit from CharacterData, which adds the data property.

Knowing this hierarchy explains why a <div> has innerHTML but a text node does not: innerHTML lives on Element, and a text node is not an element. You can confirm an object's class with Object.prototype.toString or the constructor name:

const div = document.createElement('div');
console.log(div.constructor.name);          // "HTMLDivElement"
console.log(div instanceof HTMLElement);    // true
console.log(div instanceof Element);        // true
console.log(div instanceof Node);           // true

Node types and names

Node types (nodeType)

The nodeType property is an integer that identifies the category of a node. It is read-only and is the most reliable way to branch your logic while traversing the DOM, because text and comment nodes are easy to confuse with elements. The most common values are:

  • 1 — Element node (Node.ELEMENT_NODE): an HTML or XML tag such as <div> or <p>.
  • 2 — Attribute node (Node.ATTRIBUTE_NODE): legacy; modern code reads attributes with getAttribute()/setAttribute() instead of walking attribute nodes.
  • 3 — Text node (Node.TEXT_NODE): the text between tags, including whitespace and line breaks.
  • 8 — Comment node (Node.COMMENT_NODE): an HTML <!-- ... --> comment.
  • 9 — Document node (Node.DOCUMENT_NODE): the document object itself, the root of the tree.

Prefer the named constants over the raw numbers — they read better and never change:

const div = document.createElement('div');
div.textContent = 'Hello';

console.log(div.nodeType);                          // 1
console.log(div.nodeType === Node.ELEMENT_NODE);    // true

const textNode = div.firstChild;
console.log(textNode.nodeType === Node.TEXT_NODE);  // true

<!-- snippet: html-result -->

<div id="example">Example node</div>
<script>
    const node = document.getElementById("example");
    node.innerHTML = 'Node type is: ' + node.nodeType;
</script>

Node names: nodeName vs tagName

Both properties return the name of a node, but they differ in scope:

  • nodeName exists on every node. For an element it returns the tag name; for a text node it returns "#text"; for a comment, "#comment"; for the document, "#document".
  • tagName exists only on elements. On a non-element node it is undefined.

For HTML documents, both return the tag name in uppercase ("DIV", not "div"), regardless of how you wrote the tag:

const div = document.createElement('div');
console.log(div.nodeName);             // "DIV"
console.log(div.tagName);              // "DIV"

const textNode = document.createTextNode('hi');
console.log(textNode.nodeName);        // "#text"
console.log(textNode.tagName);         // undefined

Rule of thumb: use tagName when you already know you are dealing with an element; use nodeName when you might be inspecting any node type.

<!-- snippet: html-result -->

<div id="example"></div>
<script>
    const element = document.getElementById('example');
    element.innerHTML = 'nodeName: ' + element.nodeName;
</script>

Node contents

There are four properties for reading and writing what is "inside" a node. Choosing the right one matters for correctness, performance, and security.

textContent — plain text, safe

textContent gets or sets the text of a node and all its descendants, ignoring any markup. When you read it, you get the concatenated text with tags stripped. When you write it, the string is inserted as literal text — any < or > is escaped, so it is the safe choice for displaying untrusted data:

const div = document.createElement('div');
div.innerHTML = '<b>Hi</b> there';

console.log(div.textContent);          // "Hi there"  (tags stripped)

div.textContent = '<script>alert(1)<\/script>';
console.log(div.textContent);          // "<script>alert(1)</script>"  (inert text, not executed)

<!-- snippet: html-result -->

<div id="example"></div>
<script>
  const element = document.getElementById('example');
  element.textContent = 'Updated text content';
</script>

innerHTML — markup inside the element

innerHTML gets or sets the HTML between an element's opening and closing tags. Setting it parses the string as HTML and rebuilds the children:

const div = document.createElement('div');
div.innerHTML = '<p>Para <span>one</span></p>';

console.log(div.innerHTML);            // "<p>Para <span>one</span></p>"
console.log(div.children.length);      // 1  (the <p>)

Security warning: never assign untrusted input to innerHTML. Because the browser parses it as HTML, a string like <img src=x onerror=alert(1)> becomes a real, script-running element — a classic cross-site-scripting (XSS) hole. Use textContent for user-supplied data, or sanitize before inserting.

outerHTML — the element including its own tag

outerHTML is like innerHTML but includes the element's own opening and closing tags. Writing to it replaces the element itself in the DOM, which has a surprising consequence — your variable still points at the old, now-detached node:

const div = document.createElement('div');
div.id = 'box';
div.innerHTML = 'content';

console.log(div.outerHTML);            // '<div id="box">content</div>'

// Setting outerHTML replaces the node; `div` is now stale.

nodeValue / data — text inside text and comment nodes

For text and comment nodes (which have no innerHTML), use nodeValue or its equivalent data to read and write their content:

const text = document.createTextNode('original');
console.log(text.nodeValue);           // "original"
console.log(text.data);                // "original"

text.data = 'changed';
console.log(text.nodeValue);           // "changed"

// On an element node, nodeValue is null.
const div = document.createElement('div');
console.log(div.nodeValue);            // null

Which one should I use?

PropertyWorks onReadsWriting parses HTML?Safe for untrusted input
textContentany nodeplain text of descendantsnoyes
innerHTMLelementsinner markupyesno (XSS risk)
outerHTMLelementselement + its tagyes (replaces node)no (XSS risk)
nodeValue / datatext, commentthe node's textnoyes

For more on inserting and replacing content, see Modifying the Document.

Conclusion

Reading node properties is the foundation of reliable DOM scripting. Use nodeType (with the Node.* constants) to tell node categories apart, tagName/nodeName to identify tags, and pick a content property deliberately: textContent for safe plain text, innerHTML/outerHTML when you intentionally want to parse markup, and nodeValue/data for bare text and comment nodes. Default to textContent for anything a user typed.

Practice

Practice
What does the 'nodeType' property indicate in a DOM node in JavaScript?
What does the 'nodeType' property indicate in a DOM node in JavaScript?
Was this page helpful?