Node Properties:Type, Tag and Contents

In this chapter, we are going to take an in-depth look at the DOM nodes in JavaScript. Let’s explore what they are and learn their most common properties.

DOM Node Classes

Different DOM nodes obtain various properties. For example, an element node that corresponds to tag <a> has link-related properties. The one that corresponds to <input> has input-related properties. Text nodes and element nodes are not the same. However, they have some common properties and methods that form a single hierarchy.

Each of the DOM nodes is a part of the matching built-in class.

EventTarget is the root of the hierarchy and is inherited by Node. Other DOM nodes inherit from it. To get more comprehensive information, please, look at the picture and its explanation below:

So, the classes are as follows:

  • EventTarget: it’s the root “abstract” class. That class objects are never created. So, it serves as a base.
  • Node: another “abstract” class that serves as a base for the nodes of DOM. Node provides the basic tree functionality: parentNode, nextSibling, childNodes, and more. They are considered getters. The Node class objects are never created either. However, concrete node classes inherit from it: Among them are Text ( for text nodes), Element ( for element nodes), or Comment ( for comment nodes).
  • Element a base class for the elements of DOM. It allows element-level navigation (for example, nextElementSibling, children and methods of search, such as getElementsByTagName, querySelector). A browser can support HTML, XML, well as SVG. The element class is a base for more specific classes, such as HTMLElement, SVGElement, and XMLElement.
  • HTMLElement: the basic class for all the HTMLElement. It is inherited from specific HTML elements that are the following:
  1. HTMLInputElement: it’s the class of <input> elements.
  2. HTMLBodyElement: the class of <body> elements.
  3. HTMLAnchorElement: the class of <a> elements.

We can continue counting them. Every tag has its class that can provide particular methods and properties.

So, the set of properties and methods of a particular node is the result of the inheritance.

Let’s check out a case where the DOM object serves as an <input> element. It is related to the HTMLInputElement class.

It will get methods and properties as a superposition of the following:

  • HTMLInputElement - provides input-specific properties.
  • HTMLElement - provides HTML element-methods that are used frequently.
  • Element - offers generic element methods.
  • Node - provides DOM node properties that are common.
  • EventTarget - provides support for events.
  • Also, it inherits from Object, so hasOwnProperty and other “plain object” methods are available, too.

DOM nodes belong to regular JavaScript objects. The prototype-based classes for inheritance are used by them. It is easy to see through outputting an element using console.dir(elem) in a browser. In the console, it is possible to see HTMLElement.prototype, Element.prototype and more.

Most of the browsers support the following commands: console.dir and console.log. Their arguments are output to the console. These commands do the same for JavaScript objects.

But, they are not the same for the DOM elements.

  1. console.dir(elem) demonstrates the element as a DOM object.
  2. console.log(elem) demonstrates the element DOM tree.

DOM objects are not described by using JavaScript, but a unique Interface Description Language (IDL). Usually, it’s easy-understandable.

All the properties in IDL are prepended by the type. For example, boolean, DOMString , and more. The example looks like this:

// Define HTMLInputElement
// The colon ":" means that the HTMLInputElement inherits from HTMLElement
interface HTMLInputElement: HTMLElement {
  // here go properties and methods of the  <input> elements

  // "DOMString" means the property value is a string
  attribute DOMString accept;
  attribute DOMString alt;
  attribute DOMString autocomplete;
  attribute DOMString value;

  //the boolean value property (true/false)
  attribute boolean autofocus;
  ...
  // now the method: "void" means that the method does not return value
  void select();
  ...
}

The “nodeType” property

The nodeType property represents another old way of getting the type of a DOM node.

It has got a numeric value, as demonstrated below:

  • For element nodes- element.nodeType == 1
  • For text nodes-element.nodeType == 3
  • For the document object-element.nodeType == 9

The specification includes several other values too.

Let’s check out an example:

let element = document.body;
    
    // let's examine what is it?
    console.log(element.nodeType); // 1 => element
    
    // and the first child is
    console.log(element.firstChild.nodeType); // 3 => text
    
    // for the document object type is 9
    console.log( document.nodeType ); // 9

But, you can easily use instanceof and other class-based tests to see the type of the node. Sometimes it can be more straightforward. However, you can only read with no option of changing it.

Tag: nodeName and tagName

You can read the tag of DOM node name from the properties, such as tagName or nodeName.

Here is an example of using nodeName and tagName:

console.log(document.body.nodeName); // BODY
console.log(document.body.tagName); // BODY

Now, let’s see the differences between these two properties.

First of all, tagName exists only for the Element nodes. On its turn, the nodeName is for any Node: for elements, it’s equivalent to tagName, and for other types of nodes ( for example, text, comment, and more), it contains a string with the node type.

In brief, tagName is supported by element nodes, and nodeName may say something about the other types of nodes.

The comparison of tagName and nodeName for the document and comment node will look as follows:

<!DOCTYPE html>
<html>
  <body>
    <!-- comment -->
    <script>
      // for comment
      alert( document.body.firstChild.tagName ); // undefined, not an element
      alert( document.body.firstChild.nodeName ); // #comment      
      // for document
      alert( document.tagName ); // undefined, not an element
      alert( document.nodeName ); // #document
    </script>
  </body>
</html>

In case of dealing with elements, you can use both tagName and nodeName.

Generally, the browser has two modes to process documents: HTML and XML. as a rule, HTML mode is enabled for web pages. The XML mode is used when browser gets an XML document with the Content-Type: application/xml+xhtml header.

The tagName and nodeName should always be uppercased in HTML mode. For example, it’s BODY either for <body> or <BoDy>.

For the XML mode, the case is kept “as is”. Anyway, XML is rarely used nowadays.

innerHTML: the contents

If you want to get the HTML inside the element as a string, the innerHTML property will help you do it. You can modify it as well., and it’s one of the most robust means of changing the page.

The example below demonstrates the contents of document.body, completely replacing it:

<!DOCTYPE html>
<html>
  <body>
    <p>Paragraph</p>
    <div>div</div>
    <script>
      alert( document.body.innerHTML ); // read the current contents
      document.body.innerHTML = 'The new body!'; // replace it
    </script>
  </body>
</html>

In another example, let’s insert not valid HTML, to see how the browser fixes the errors:

<!DOCTYPE html>
<html>
  <body>
    <script>
      document.body.innerHTML = '<b>test'; // forgot to close the tag
      alert( document.body.innerHTML ); // <b>test</b> (fixed)
    </script>
  </body>
</html>

Be careful: “innerHTML+=” will do a full overwrite.

You can append HTML to an element enforcing element.innerHTML+="more html", like in the example below:

div.innerHTML += "
<div>Welcome<img src=' '/> !</div>
";
div.innerHTML += "How goes?";

But, please note that you need to do it very carefully as it leads to a full overwrite.

The two lines, demonstrated below, technically do the same:

element.innerHTML += "...";
// is a shorter way to write:
element.innerHTML = element.innerHTML + "...";

When the content is zeroed-out and rewritten, the overall images and other resources can be reloaded.

outerHTML: full HTML of the element

This property includes the full HTML of the element. It looks similar to innerHTML plus the element itself, like here:

let div = document.createElement('div');
div.id = 'elem';
div.innerHTML = "Welcome to";


document.body.appendChild(div);
let b = document.createElement('b');
b.innerHTML = "W3Docs";
div.appendChild(b);

alert(div.outerHTML); // <div id="elem"> Welcome to <b>W3Docs</b></div>

Again, you need to be careful: in contrast to innerHTML , writing to outerHTML will not change the element, but will replace it in the DOM. It may sound strange, and that’s why let’s consider an example:

let div = document.createElement('div');
div.id = 'elem';
div.innerHTML = "Welcome to W3Docs";

document.body.appendChild(div);

let d = document.querySelector('div');

// replace div.outerHTML with <p>...</p>
d.outerHTML = '<p>New element</p>'; // (*)

// 'div' is still the same
alert(div.outerHTML); // <div>Welcome to W3Docs</div> (**)

In the line (*), div is replaced with <p>New element</p> . In the outer document, the content can be seen instead of <div>. But the most surprising fact is that in the line (**) the value of the old div variable is not changed.

The outerHTML assignment will not change the DOM element but remove it from the DOM, as well as, insert the new HTML in its place.

So, an error can be made here easily. Modifying div.outerHTML and then continuing to work with div as if it had the new content. In fact, it doesn’t. This kind of thing can be correct for innerHTML, but not for outerHTML.

You can also write to elem.outerHTML. But, note that it will not change the element you are writing to.

nodeValue/data: Text Node Content

The innerHTML property is acceptable only for element nodes. Text nodes and other node types have got a counterpart: nodeValue and data properties. In practice, they are almost the same. Still, there are some minor differences. The data is shorter, hence more convenient in use.

An illustration of reading the content of a text node along with the comment is shown below:

<!DOCTYPE html>
<html>
  <body>
    Welcome
    <!-- Comment -->
    <script>
      let text = document.body.firstChild;
      alert(text.data); // Welcome      
      let comment = text.nextSibling;
      alert(comment.data); // Comment
    </script>
  </body>
</html>

For text codes, there can be a reason for reading or modifying them. But what about the comments?

At times, programmers insert information or template instructions into HTML, as in the following example:

<!-- if isBook -->
<div>Welcome to Javascript book</div>
<!-- /if -->

Afterward, JavaScript will be capable of reading it from data property and process embedded instructions.

textContent: Pure Text

This property allows accessing the text inside the element. It’s about only the text without any <tag>.

Here is an example of using the textContent property:

<!DOCTYPE html>
<html>
  <body>
    <div id="text">
      <h1>Headline.</h1>
      <p>Welcome to W3Docs</p>
    </div>
    <script>
      // Headline. Welcome to W3Docs
      alert(text.textContent);
    </script>
  </body>
</html>

In the example above, you can notice that only the text is returned without the <tags>, as though the tags were cut out.

It is much more useful to write to textContent as it allows writing the text most safely.

The “hidden” Property

The “hidden” property indicates whether the element is visible or not. It can be used in HTML or assigned using JavaScript, as it is demonstrated in the following example:

<!DOCTYPE html>
<html>
  <body>
    <div>W3Docs </div>
    <div hidden> First text "hidden"</div>
    <div id="elem">Second text "hidden"</div>
    <script>
      elem.hidden = true;
    </script>
  </body>
</html>

The “hidden” property technically operates the same as style="display:none". But it’s much shorter to write. A blinking element will look like this:

<!DOCTYPE html>
<html>
  <body>
    <div id="elem">A hidden element</div>
    <script>
      setInterval(() => elem.hidden = !elem.hidden, 1000);
    </script>
  </body>
</html>

And using only javascript code:

var div = document.createElement("div");
div.id = 'elem';
div.innerHTML = 'Welcome to W3docs';
document.body.appendChild(div);

setInterval(() => elem.hidden = !elem.hidden, 1000);

Additional Properties

There exist additional properties of DOM elements. Here are the ones that depend on class, in particular:

  • value: means the value for <input> , <select> and <textarea> (HTMLInputElement,HTMLSelectElement, and so on).
  • href: for a <a href="..."> (HTMLAnchorElement).
  • id: means the value of the id attribute for the overall elements (HTMLElement).

Here is an example of using additional properties above:

<!DOCTYPE html>
<html>
  <body>
    <input type="text" id="inputElem" value="value">
    <script>
      alert(inputElem.type); // "text"
      alert(inputElem.id); // "inputElem"
      alert(inputElem.value); // value
    </script>
  </body>
</html>

And using only javascript code:

var input = document.createElement("input");
input.setAttribute("type", "text");
input.id = 'inputElem';
input.value = 'value';
document.body.appendChild(input);

console.log(input.type); // "text"
console.log(input.id); // "inputElem"
console.log(input.value); // value

Summary

To sum up, we can state that every DOM node belongs to a particular class. The classes, on their turn, represent a hierarchy. The set of methods and properties is the result of inheritance. The main DOM properties are nodeType,nodeName/tagName,innerHTML,outerHTML,nodeValue/data, textContent,hidden. There are also additional properties that depend on their class.




Do you find this helpful?

Related articles