Lesson 05-DOM Manipulation

Concepts

The smallest unit of the DOM is called a node. The tree-like structure of a document (DOM tree) is composed of various types of nodes. There are seven types of nodes:

  • Document: The top-level node of the entire document tree (Node.DOCUMENT_NODE === 9).
  • DocumentType: The <!DOCTYPE> tag (Node.DOCUMENT_TYPE_NODE === 10).
  • Element: HTML tags in the webpage (Node.ELEMENT_NODE === 1).
  • Attr: Attributes of webpage elements (e.g., class="right") (Node.ATTRIBUTE_NODE === 2).
  • Text: Text between or within tags (Node.TEXT_NODE === 3).
  • Comment: Comments (Node.COMMENT_NODE === 8).
  • DocumentFragment: A document fragment (Node.DOCUMENT_FRAGMENT_NODE === 11).

Node Interface

Node Properties

  • Node.prototype.nodeType: Returns an integer indicating the node’s type.
  • Node.prototype.nodeName: Returns the node’s name.
  • Node.prototype.nodeValue: Returns a string representing the node’s text value; readable and writable.
  • Node.prototype.textContent: Returns the text content of the node and all its descendants.
  • Node.prototype.baseURI: Returns a string representing the absolute URL of the current webpage, used by browsers to calculate relative URLs.
  • Node.prototype.ownerDocument: Returns the top-level document object (document) containing the node.
  • Node.prototype.nextSibling: Returns the first sibling node immediately following the current node, or null if none exists.
  • Node.prototype.previousSibling: Returns the closest preceding sibling node, or null if none exists.
  • Node.prototype.parentNode: Returns the parent node, which can only be an element node, document node, or document fragment node.
  • Node.prototype.parentElement: Returns the parent element node, or null if the parent is not an element or does not exist.
  • Node.prototype.firstChild: Returns the first child node, or null if none exists.
  • Node.prototype.lastChild: Returns the last child node, or null if none exists.
  • Node.prototype.childNodes: Returns an array-like object (NodeList) containing all child nodes.
  • Node.prototype.isConnected: Returns a boolean indicating whether the node is part of the document.

Node Methods

  • Node.prototype.appendChild(): Inserts a node as the last child of the current node, returning the inserted node.
  • Node.prototype.hasChildNodes(): Returns a boolean indicating whether the node has child nodes.
  • Node.prototype.cloneNode(): Clones the node, accepting a boolean parameter to indicate whether to clone child nodes; returns the cloned node.
  • Node.prototype.insertBefore(): Inserts a node at a specified position within the parent node.
  • Node.prototype.removeChild(): Removes a specified child node, returning the removed node.
  • Node.prototype.replaceChild(): Replaces a child node with a new node.
  • Node.prototype.contains(): Returns a boolean indicating whether the parameter node meets specific conditions (e.g., is a descendant).
  • Node.prototype.compareDocumentPosition(): Returns a six-bit binary value indicating the relationship between the parameter node and the current node (similar to contains).
  • Node.prototype.isEqualNode(): Returns a boolean checking if two nodes are equal in type, attributes, and child nodes.
  • Node.prototype.isSameNode(): Returns a boolean checking if two nodes are identical (same instance).
  • Node.prototype.normalize(): Cleans up text nodes within the current node, removing empty text nodes and merging adjacent ones.
  • Node.prototype.getRootNode(): Returns the root node (document) of the current node’s document, equivalent to ownerDocument.

NodeList Interface and HTMLCollection Interface

The DOM provides two node collections for holding multiple nodes: NodeList and HTMLCollection. Both are interface specifications, and many DOM properties and methods return instances of these. The main difference is that NodeList can include various node types, while HTMLCollection only includes HTML element nodes.

NodeList Interface

Obtaining a NodeList instance:

  • Node.childNodes
  • Node search methods like document.querySelectorAll()
var children = document.body.childNodes;
Array.isArray(children) // false
children.length // 34
children.forEach(console.log)
// Node traversal
for (var i = 0; i < children.length; i++) {
  var item = children[i];
}
// Or use forEach
children.forEach(function f(item, i, list) {
  // ...
}, this);
// Or use NodeList.prototype.keys(), NodeList.prototype.values(), NodeList.prototype.entries()
// Convert to array
var nodeArr = Array.prototype.slice.call(children);
// length property returns the number of nodes in the NodeList
document.querySelectorAll('xxx').length
// item method returns the member at the specified index
document.body.childNodes.item(0)

HTMLCollection Interface

HTMLCollection is a collection of element nodes only. It returns an array-like object but, unlike NodeList, lacks a forEach method, requiring a for loop for traversal.

document.links instanceof HTMLCollection // true
var pic = document.getElementById('pic');
document.images.pic === pic // true
// length property returns the number of members
document.links.length // 18
// item method returns the member at the specified index
var c = document.images;
var img0 = c.item(0);
// namedItem method returns the element node matching the id or name attribute
document.images.namedItem('pic') === pic // true

ParentNode Interface and ChildNode Interface

The ParentNode interface indicates that a node is a parent, providing methods to manage child nodes. The ChildNode interface indicates a node is a child, offering related methods.

ParentNode Interface

  • ParentNode.children: Returns an HTMLCollection of all element child nodes (read-only).
  • ParentNode.firstElementChild: Returns the first element child node, or null if none exists.
  • ParentNode.lastElementChild: Returns the last element child node, or null if none exists.
  • ParentNode.childElementCount: Returns an integer indicating the number of element child nodes, or 0 if none exist.
  • ParentNode.append(), ParentNode.prepend(): Appends one or more child nodes after the last element child or before the first element child, respectively. No return value.

ChildNode Interface

  • ChildNode.remove(): Removes the current node from its parent.
  • ChildNode.before(), ChildNode.after(): Inserts one or more sibling nodes before or after the current node, sharing the same parent.
  • ChildNode.replaceWith(): Replaces the current node with the specified node (element or text node).

Document Node

  • document.defaultView: Returns the window object associated with the document.
  • document.doctype: Returns the document type.
  • document.documentElement: Returns the root element node (e.g., <html>).
  • document.body: Points to the <body> node.
  • document.head: Points to the <head> node.
  • document.scrollingElement: Returns the scrolling element of the document.
  • document.activeElement: Returns the currently focused DOM element.
  • document.fullscreenElement: Returns the DOM element currently in fullscreen mode.
  • document.links: Returns all <a> and <area> nodes with an href attribute.
  • document.forms: Returns all form nodes.
  • document.images: Returns all <img> nodes.
  • document.embeds: Returns all <embed> nodes.
  • document.plugins: Returns all <embed> nodes.
  • document.scripts: Returns all <script> nodes.
  • document.styleSheets: Returns the collection of embedded or linked stylesheets.
  • document.documentURI: Returns a string representing the document’s URL.
  • document.URL: Returns a string representing the document’s URL.
  • document.domain: Returns the document’s domain, excluding protocol and port.
  • document.location: A native browser object providing URL-related information and methods.
  • document.lastModified: Returns a string indicating the document’s last modification time.
  • document.title: Returns the document’s title.
  • document.cookie: Used to manipulate browser cookies.
  • document.designMode: Controls whether the document is editable ("on" or "off"; default is "off"). When "on", the entire document becomes editable.
  • document.currentScript: Returns the DOM node of the current script (inline or external).
  • document.implementation: Returns a DOMImplementation object.
  • document.open(): Clears the document’s content, making it writable for document.write.
  • document.close(): Closes a document opened by document.open.
  • document.write(): Writes content to the document.
  • document.querySelector(): Returns the first element node matching a CSS selector.
  • document.querySelectorAll(): Returns a NodeList of all nodes matching a CSS selector.
  • document.getElementsByTagName(): Returns elements matching an HTML tag name.
  • document.getElementsByClassName(): Returns an HTMLCollection of elements with the specified class, updating live with changes.
  • document.getElementsByName(): Returns HTML elements with the specified name attribute.
  • document.getElementById(): Returns the element node matching the specified id, or null if none exists.
  • document.elementFromPoint(): Returns the topmost element node at the specified page coordinates.
  • document.elementsFromPoint(): Returns all element nodes at the specified page coordinates.
  • document.createElement(): Creates and returns an element node.
  • document.createTextNode(): Creates and returns a text node.
  • document.createAttribute(): Creates and returns an attribute node (Attr).
  • document.createComment(): Creates and returns a comment node.
  • document.createDocumentFragment(): Creates an empty DocumentFragment.
  • document.createEvent(): Creates an event object (Event) for use with element.dispatchEvent.
  • document.addEventListener(): Adds an event listener.
  • document.removeEventListener(): Removes an event listener.
  • document.dispatchEvent(): Triggers an event.
  • document.hasFocus(): Returns a boolean indicating whether an element in the document is focused.
  • document.adoptNode(): Removes a node and its children from its original document or DocumentFragment.
  • document.importNode(): Copies a node and its children from another document or DocumentFragment to the current document.
  • document.createNodeIterator(): Returns a node iterator for child nodes.
  • document.createTreeWalker(): Returns a DOM subtree iterator.

Element Node

Instance Properties

  • Element-related properties (e.g., attributes).
  • State-related properties.
  • Element.attributes: The element’s attributes.
  • Element.className, Element.classList: The element’s class name(s).
  • Element.dataset: Custom data attributes.
  • Element.innerHTML: The element’s inner HTML content.
  • Element.outerHTML: The element’s outer HTML content.
  • Element.clientHeight, Element.clientWidth: The element’s visible dimensions.
  • Element.clientLeft, Element.clientTop: The element’s border offsets.
  • Element.scrollHeight, Element.scrollWidth: The element’s total scrollable dimensions.
  • Element.scrollLeft, Element.scrollTop: The element’s scroll offsets.
  • Element.offsetParent: The element’s offset parent.
  • Element.offsetHeight, Element.offsetWidth: The element’s total dimensions, including borders.
  • Element.offsetLeft, Element.offsetTop: The element’s position relative to its offset parent.
  • Element.style: The element’s inline styles.
  • Element.children, Element.childElementCount: The element’s child elements and their count.
  • Element.firstElementChild, Element.lastElementChild: The first and last element children.
  • Element.nextElementSibling, Element.previousElementSibling: The next and previous sibling elements.

Instance Methods

  • Attribute-related methods.
  • Element.querySelector(): Selects the first matching element.
  • Element.querySelectorAll(): Selects all matching elements.
  • Element.getElementsByClassName(): Selects elements by class name.
  • Element.getElementsByTagName(): Selects elements by tag name.
  • Element.closest(): Finds the closest ancestor matching a selector.
  • Element.matches(): Checks if the element matches a selector.
  • Event-related methods.
  • Element.scrollIntoView(): Scrolls the element into view.
  • Element.getBoundingClientRect(): Returns the element’s bounding rectangle.
  • Element.getClientRects(): Returns a collection of the element’s rectangles.
  • Element.insertAdjacentElement(): Inserts an element at a specified position.
  • Element.insertAdjacentHTML(), Element.insertAdjacentText(): Inserts HTML or text at a specified position.
  • Element.remove(): Removes the element.
  • Element.focus(), Element.blur(): Sets or removes focus.
  • Element.click(): Simulates a click.

Attribute Operations

Element nodes provide six methods for attribute manipulation:

  • getAttribute(): Returns the attribute value as a string.
  • getAttributeNames(): Returns an array of all attribute names.
  • setAttribute(): Adds a new attribute to the element.
  • hasAttribute(): Returns a boolean indicating whether the attribute exists.
  • hasAttributes(): Returns a boolean indicating whether the element has any attributes.
  • removeAttribute(): Removes the specified attribute; no return value.

Text Node and DocumentFragment Node

Text Node Properties

  • data: Equivalent to nodeValue, used to set or read the text node’s content.
  • wholeText: Returns the current text node and adjacent text nodes as a single string.
  • length: Returns the text node’s character length.
  • nextElementSibling: Returns the element node immediately following the text node, or null if none exists.
  • previousElementSibling: Returns the closest preceding element node, or null if none exists.

Text Node Methods

  • appendData(): Appends a string to the text node.
  • deleteData(): Deletes a substring, accepting start position and length as parameters.
  • insertData(): Inserts a string at the specified position.
  • replaceData(): Replaces a substring, accepting start position, length, and replacement string.
  • subStringData(): Returns a substring, accepting start position and length.
  • remove(): Removes the text node.
  • splitText(): Splits the text node into two adjacent text nodes.

CSS Operations

HTML Element’s style Property

The simplest way to manipulate CSS styles is using the element node’s getAttribute(), setAttribute(), and removeAttribute() methods to directly read, write, or delete the style attribute.

CSSStyleDeclaration Instance Methods

  • CSSStyleDeclaration.getPropertyPriority(): Returns a string indicating whether a CSS property has the !important priority ("important" or an empty string).
  • CSSStyleDeclaration.getPropertyValue(): Returns the value of the specified CSS property as a string.
  • CSSStyleDeclaration.item(): Returns the CSS property name at the specified index.
  • CSSStyleDeclaration.removeProperty(): Removes a CSS property, returning its original value.
  • CSSStyleDeclaration.setProperty(): Sets a new CSS property; no return value.

CSS Object

  • CSS.escape(): Escapes special characters in CSS selectors.
  • CSS.supports(): Returns a boolean indicating whether the environment supports a CSS rule.
  • window.getComputedStyle(): Returns computed styles; inline styles have the highest priority and reflect changes immediately.

CSS Pseudo-Elements

var test = document.querySelector('#test');
var result = window.getComputedStyle(test, ':before').content;
var color = window.getComputedStyle(test, ':before').color;

Adding Stylesheets

// Method 1
var style = document.createElement('style');
style.setAttribute('media', 'screen');
style.innerHTML = 'body{color:red}';
document.head.appendChild(style);
// Method 2
var style = (function() {
  var style = document.createElement('style');
  document.head.appendChild(style);
  return style;
})();
style.sheet.insertRule('.foo{color:red;}', 0);

Mutation Observer API

The Mutation Observer API monitors DOM changes, such as node additions/removals, attribute changes, or text content modifications. It is event-like, as DOM changes trigger Mutation Observer callbacks. Unlike events, which are synchronous, Mutation Observer is asynchronous: changes are not processed immediately but are deferred until all current DOM operations complete.

var article = document.querySelector('article');
var options = {
  'childList': true,
  'attributes': true
};
observer.observe(article, options);
Share your love