Walking the DOM and Modifying Nodes
Walking the DOM
- In addition to selector methods, it is also possible to move around within the DOM tree in a more methodical fashion, accessing parent nodes, child nodes, siblings, etc.
- Often you would use a selector method to pinpoint an element, or create a node list of elements to loop through, and then "walk" from there to a parent element node, a child node, a sibling node, etc.
- All of these properties and methods are part of the DOM, which means that they will work in XML documents too.
Methods and Properties for Walking the DOM
childNodes[]- Stored as a dynamic node list and indexed by number; allows access to the children nodes one level down in the document tree. To access children even further down (grandchildren, great-grandchildren) requires further document path information. Has alengthproperty reflecting the number of child nodes.closest("CSS selector")- This method accepts a CSS selector as a string and finds the closest ancestor element node that matches the CSS. Returnsnullif no match is found.firstChild- The first child node of the currently accessed element node. This could be a text node or comment node.firstElementChild- The first child element node of the currently accessed element node. Ignores text nodes and comment nodes.lastChild- The last child node of the currently accessed element node. This could be a text node or comment node.lastElementChild- The last child element node of the currently accessed element node. Ignores text nodes and comment nodes.nextSibling- The next node at the same level of the document tree; they have the same parent node. This could be a text node or comment node.nextElementSibling- The next element node at the same level of the document tree. Ignores text nodes and comment nodes.previousSibling- The previous node at the same level of the document tree; they have the same parent node. This could be a text node or comment node.previousElementSibling- The previous element node at the same level of the document tree. Ignores text nodes and comment nodes.parentNode- The parent node of the currently accessed element. Each node can have only one parent node (which is guaranteed to be an element node).
Walking the DOM Example
See the Pen Walking the DOM by Jason Withrow (@jwithrow) on CodePen.
Inspecting a Node
In some cases (such as when moving up and down the DOM tree / hierarchy), it is beneficial to know what node you are currently accessing or some details about that node. These properties provide that information.
| Property / Method | Description | Node |
|---|---|---|
| hasAttribute("attributename") |
This method is passed a single parameter, which is a string containing the attribute name.
Returns |
Element |
| hasAttributes() | Returns true if the selected node has at least one attribute defined; false if there are no attributes defined. |
Element |
| hasChildNodes() | Returns true if the selected node has child nodes; false if there are no child nodes. |
Element |
| nodeName |
Returns the name of the node.
|
Any |
| nodeType |
Returns a number to represent node type:
|
Any |
| tagName |
Returns the name of the tag.
Not as versatile as |
Element |
Getting and Setting Element Node Properties / Attribute Nodes
Dot Notation
- Dot notation (e.g.,
elementNodeReference.property) is a well-established and reliable method of reading and setting properties. - Implementation considerations:
- When referencing the
hrefproperty of an anchor (<a></a>) using dot notation the absolute URL is always returned. This is a good thing; it is consistent cross-browser. - Some properties need to be written in camelCase (such as
tabIndex,colSpan, androwSpan) to work across all browsers. The capitalization of these in your HTML code makes no difference.
- When referencing the
- There are some limitations of dot notation:
- Reserved words cannot be used in the dot notation, so class becomes
className. - Every dot requires an object lookup, but these are short chains so the performance hit is negligible.
- Reserved words cannot be used in the dot notation, so class becomes
Square Braces Notation
- Also called subscript notation; this is an alternative to dot notation.
- What is expressed in dot notation as
theLink.title = 'Example'is expressed astheLink['title'] = 'Example' - The primary advantage of this approach is that it represents the property / method as a string, which enables reserved words to be used and allows you to assemble the property name on-the-fly (in contrast, dot notation values are literals and cannot be assembled using
+and variables). - I typically use this notation only when I need its string concatenation flexibility and dynamic nature.
getAttribute() and setAttribute()
- The dot notation and square braces notation are both parts of JavaScript Core, which means that the syntax is part of the JavaScript language.
- In contrast,
getAttribute()andsetAttribute()are DOM methods that can be called for element nodes. getAttribute()retrieves the value of the indicated attribute, which is passed as a string inside the parentheses.const idVal = elementRef.getAttribute("id");setAttribute()is passed two strings, the first of which is the attribute and the second is the new value.elementRef.setAttribute("id","topnav");- These two DOM methods have the advantage of working with XML documents as well as HTML documents.
- HTML5 introduced custom
data-attributes, which is any attribute starting withdata-. These are very useful andgetAttribute()andsetAttribute()are ideal for working with them.Attributes can have as many hyphen-separated words as desired (e.g.,
data-current-state="inactive"in the HTML). To get and set this custom attribute via JavaScript:const elState = elementRef.getAttribute("data-current-state"); elementRef.setAttribute("data-current-state","active");
The classList API
- Working with the
classattribute in HTML is a common occurrence. - Classes are unique in allowing multiple space-separated values to be provided (the vast majority of HTML attributes only support a single value, or a single "token" in the language of the specifications).
- Historically, this multi-value setup has meant that JavaScript approaches have needed to carefully manipulate the string of space-separated values, to avoid damaging or accidentally removing something within that string.
- The
.classNameproperty treats the entireclassattribute value as one readable / writable string. For some purposes, this is fine. For more complicated situations, something more is needed. - The
classListAPI was created for these more complicated scenarios, as it treats all the individual classes assigned to an element as a live collection of tokens that can be modified.
classList Methods
add()- Accepts one or more quoted classes, to add to what is already there.elementRef.classList.add("someclass");remove()- Removes one or more quoted classes, if they exist.elementRef.classList.remove("someclass");replace()- Accepts two quoted class names. The first is the one to find; the second is the class to replace it with.elementRef.classList.replace("classToSwapOut", "replacementClass");toggle()- Accepts a single quoted class name as the first parameter and an optional second parameter, if there is conditional logic that needs to betruefor the toggle to happen.If the toggle goes forward and the class is already there, it is removed. If it is not there yet, it is added.
// single parameter elementRef.classList.toggle("someclass"); // 2 parameters elementRef.classList.toggle("someclass", x > 5);contains()- Accepts a single quoted class name. If the class is already present, it returnstrue, otherwise it returnsfalse.elementRef.classList.contains("someclass");