Register to get access to free programming courses with interactive exercises

Managing DOM Nodes JS: DOM API

Properties of specific elements are the largest part of the DOM API. In this lesson, we'll examine only the basic properties, solely to show the principles of how they work. In everyday practice, programmers refer to the documentation to find out what properties and methods nodes have to manage them.

Attributes

Each tag in HTML has attributes. Some of them are common to all tags, others are specific to certain ones:

<a id="aboutPage" href="/pages/about" class="simple">About</a>

In the example above, you see the id and class attributes, we can use them with any tag. On the other hand, there ishref attribute, which only goes with the <a> and a few other tags.

Once the browser has loaded the HTML code, it will build the DOM based on it. During processing, each tag becomes a node, and its attributes become properties of this node. Usually, the attributes' names and properties of nodes coincide:

// <a id="aboutPage" href="/pages/about" class="simple">About</a>
const el = document.querySelector('#aboutPage');
el.id; // aboutPage
el.href; // https://hexlet.io/pages/about

There are some exceptions. For example, the class attribute corresponds to the className property. There are several additional ways of working with classes conveniently.

There can be any number of classes, set by a regular text string. Accordingly, if you need to change this list, you'll have to work with strings, which is incredibly inconvenient.

Here's how you can do it using a DOM tree:

// A tag with this id has the string "simple"
const el = document.querySelector('#aboutPage');
el.classList.add('page');
el.classList.remove('simple');
// After all, changes have been made
el.className; // page

Additional methods:

  • el.classList.contains("class") – it checks whether the element contains the required class and returns true or false
  • el.classList.toggle("class") – if there is a class, it removes it, and vice versa

Naming is not the only difference between attributes and properties. There are many more differences, and they are not always obvious. Here are just a few of them:

  1. An attribute is always a string, but properties can be other things. For example:

    <textarea rows="5"></textarea>
    

    The value of the rows property of the corresponding element in the DOM tree will be a number.

  2. Attributes are not case-sensitive:

    <a Id="aboutPage" hrEf="/pages/about" CLASS="simple">About</a>
    

    It is best to be consistent, but at least knowing that it will work either way is useful.

  3. The attribute is always in HTML, so it is accessible via innerHTML. But many properties do not have corresponding attributes. For example, the <a> tag has a hash property, but there is no hash attribute.

As we saw above, attributes and properties are not the same. Therefore, there's a set of methods for managing attributes:

  • el.hasAttribute(name) – checks if the attribute exists
  • el.getAttribute(name) – gets the value of the attribute
  • el.setAttribute(name, value) – sets the attribute
  • el.removeAttribute(name) – deletes the attribute
  • el.attributes – list of HTML attributes
// The methods work with html attributes
el.getAttribute('class');

Note that they work with attributes (and their names), not properties. They make it possible to both extract them and change them. You may want to know if the attribute will change when you change the property, and vice versa.

Synchronization works like so: when the attribute changes, the property will be updated automatically. But there are exceptions. Despite all this, it does not mean you should try and work via attributes. On the contrary, whenever possible, always work with DOM tree properties, and use read-only attributes to get the state of the DOM during initialization (HTML parsing):

<a id="aboutPage" href="/pages/about" class="simple">About</a>
const el = document.querySelector('#aboutPage');
el.setAttribute('class', 'page');
el.className; // page
el.getAttribute('class'); // page

Unlike properties, the attribute value always matches what we see in HTML, but properties are sometimes normalized:

<!-- At this moment, the browser is open on https://hexlet.io -->
<a id="link-to-courses" href="/courses">Courses</a>
const el = document.querySelector('#link-to-courses');
el.href; // https://hexlet.io/courses
el.getAttribute('href'); // /courses

Non-standard attributes never turn into properties of the corresponding DOM tree elements. E.g., if we add the href attribute to the p tag, it will be ignored. However, this doesn't mean we can't extract it using getAttribute.

To work with arbitrary properties, HTML has a special data-* attribute, where any word can stand in place of an asterisk:

<a href="#" data-toggle="tab">My projects</a>

Programmers actively use these attributes in JavaScript plugins to not get tied up with classes. In DOM elements, they're accessible by a property called dataset:

console.log(el.dataset.toggle); // => tab

Inside the dataset object, the name of each property is a string after data- in the attribute. If the name contains a hyphen, it gets deleted, and the letter after it becomes a capital letter:

<a href="#" data-nav-toggle="tab">My projects</a>
console.log(el.dataset.navToggle); // => tab

Features

The set of properties also changes depending on the element's type, except those inherited from Node and Element.

You can refer to the specification to see a list of these properties. We describe them in a format that's easy to understand:

// HTMLLinkElement – it is just the name of the interface
// HTMLElement – the parent type that properties and methods are inherited from
// attribute – designation of a specific attribute, and its type and name
interface HTMLLinkElement : HTMLElement {
  // The last word in each line is the name of the property in the object
  attribute USVString href;
  attribute DOMString? crossOrigin;
  attribute DOMString rel;
  attribute RequestDestination as; // (default "")
  readonly attribute DOMTokenList relList;
  attribute DOMString media;
  attribute DOMString nonce;
  attribute DOMString integrity;
  attribute DOMString hreflang;
  attribute DOMString type;
}

As with navigating DOM trees, there's no need to remember everything about how attributes and properties behave. You'll get a good idea by practicing and experimenting.


Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
130
courses
1000
exercises
2000+
hours of theory
3200
tests

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

Bookmate
Health Samurai
Dualboot
ABBYY
Suggested learning programs
profession
Development of front-end components for web applications
10 months
from scratch
Start at any time

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending this form, you agree to our Personal Policy and Service Conditions
Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.