--- id: create-modify-element # sidebar_label: DOM Manipulation title: DOM Manipulation slug: / --- import Admonition from "../components/Admonition" import Accordion from "../components/Accordion" import InternalLink from "../components/InternalLink" import MDN from "../components/MDNBadge" :::note DOM interfaces Every kind of **DOM** node is represented by an interface based on **Node** interface. **Element, Document and DocumentFragment** interfaces inherit from Node. More about DOM interfaces [here](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) ::: ## Finding elements ### 1. querySelector() `document.querySelector(selector) : Element | null` This method returns the **first element that matches the CSS selector**. If no match is found, it returns `null`. ```js //
document.querySelector(".box"); // returns .box document.querySelector(".not-found"); // null ``` Besides Document, this method is also available on Element and DocumentFragment.
If you want to look within a specific element, just use ele.querySelector() on the parent element.
If you want to look within a specific fragment, just use df.querySelector() on the parent fragment. ```js // Example - outer is a parent element/fragment. let innerEle = outer.querySelector(".inner"); ```
### 2. querySelectorAll() `document.querySelectorAll(selector) : NodeList` This method returns **all the elements that match** the specified CSS selector. It returns a **static NodeList**, which contains the matching elements. If no match is found, it returns empty NodeList. :::note How to consume NodeList? NodeList is a iterable, so it can be iterated using `for..of` loop, or converted to a array using spread syntax like `[...nodelist]`. Here, the NodeList is static - meaning any changes in the DOM later does not affect the content of the existing collection. More about NodeList [here](https://developer.mozilla.org/en-US/docs/Web/API/NodeList). ::: ```js let paras = document.querySelectorAll("p"); for (let p of paras) { p.className = "note"; } ``` `querySelectorAll` is also available on Element and DocumentFragment, in the same way as querySelector. ## Create / insert element ### 3. createElement() `document.createElement(tagName) : Element` This method creates a new HTML element, taking the specified HTML tag name as argument. ```js document.createElement("div") // creates a
element ``` To add some text inside a element, you'll need to create a text node. `createTextNode` method takes a string as input and returns a new TextNode. ```js let ele = document.createElement("div") let newText = document.createTextNode("Hello world") ele.appendChild(newText) //
Hello world
```
### 4. setAttribute() `Element.setAttribute(name, value)` This method sets an attribute on the current element. `name` - name of the attribute to add. Ex- "type". `value` - value of the attribute. Ex- "text". ```js let ele = document.createElement("input") ele.setAttribute("type", "text") // ``` ### 5. appendChild() `Node.appendChild(newNode)` This method inserts a new node as the last child of the parent node. ```js let eleDiv = document.createElement("div") let eleH1 = document.createElement("h1") eleDiv.appendChild(eleH1) //

``` If newNode is already a child of another node, then it is removed from its existing parent and then added to the new parent. If newNode is a DocumentFragment, then - instead of adding the fragment itself as a child, the entire content of the fragment is added as children of the parent node. There is a newer api called .append(), which is a superset of .appendChild().

⭐️ .append() allows you to insert multiple child elements in a single call. It also allows string as input, which gets converted to Text node. ```js ele1.append(ele2, ele3, 'hello world') ``` 💔 .appendChild() only allows inserting a single element at a time.
### 6. removeChild() `Node.removeChild(childNode)` This method tries to remove a child node from the parent and returns the removed node. If the node to be removed is not a child of the parent node, it throws a `NotFoundError` DOMException. ```js //
//
//
parentEle.removeChild(childEle) ``` ### 7. insertBefore() `Node.insertBefore(newEle, refEle)` This method inserts a new child node before another node within a parent. It also works with **DocumentFragment**, by inserting all of its content in that position. `newEle` - The node to be inserted. `refEle` - The reference node before which newEle should be inserted. If refEle is `null`, then newEle is added as the last child. ```js //
    //
  • Apple
  • //
  • Zebra
  • //
// To add a new
  • above "Zebra" let parent = document.querySelector("ul") let ref = document.querySelector("li:last-child") let newEle = document.createElement("li") parent.insertBefore(newEle, ref) ``` :::note insertAfter() There is no `insertAfter()` method. It can be emulated by combining insertBefore method with ele.nextSibling. ```js parent.insertBefore(newEle, ref.nextSibling) ``` ::: ### 8. Document Fragment `document.createDocumentFragment() : DocumentFragment` This method is used to create a new empty document fragment. DocumentFragment can be considered to be a off-screen lightweight `document` object. It is generally used for batching multiple operations - by doing them in the fragment over time and then rendering the whole content to the visible DOM in one shot . Because fragment is not rendered, making changes to it doesn't cause any performance impact (no reflow). To **actually "render" the fragment** in the visible document, use appendChild or `insertBefore`. ```js let fragment = document.createDocumentFragment() // Insert / modify elements in fragment // in dom,
    let outerEle = document.querySelector(".outer") outerEle.appendChild(fragment) // This will remove all content from fragment and // insert them within outerEle. ``` -------- In the next section, we'll see how to read information from a DOM element.