---
id: create-modify-element
# title: Create / modify DOM nodes
# sidebar_label: DOM Manipulation
title: DOM Manipulation
slug: /
---

import Admonition from "../components/Admonition"
import Accordion from "../components/Accordion"
import MDN from "../components/MDNBadge"

## Finding elements

### 1. `querySelector()`

This method returns the **first element that matches the CSS selector**. If no match is found, it returns `null`.

```js
document.querySelector(selector);

// Ex- .container > .box
document.querySelector(".box"); // returns .box
document.querySelector(".not-found"); // null
```

<Accordion>
  <Admonition type="note" title="Extra">
  This method is also available on all DOM nodes. If you want to look within a specific element, this is very useful.

  ```js
  // Example - .outer > .inner
  outerEle.addEventListener((ev) => {
    var innerEle = ev.target.querySelector(".inner");
  });
  ```
  </Admonition>
</Accordion>

<MDN title="querySelector" url="https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector" />

### 2. `querySelectorAll()`

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
var paras = document.querySelectorAll("p");

for (var p of paras) {
  p.className = "note";
}
```

<MDN title="querySelectorAll" url="https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll" />

## Create / insert element

### 1. `createElement()`

It creates a new HTML element, taking the tag name (`"div"`) as argument.

To set attributes and add the element to DOM, look at `.setAttribute` and `.appendChild` below.

```js
document.createElement("div")
// creates <div/>
```

<Accordion title="Related">
  <Admonition type="note" title="Creating text node">
    To add some text inside a element, you'll need to create a <b>text node</b>. 
    `createTextNode` method takes a string as input and returns a new TextNode.

  ```js
  var ele = document.createElement("div")
  var newText = document.createTextNode("Hello world")

  ele.appendChild(newText) 
  // <div>Hello world</div>
  ```
  </Admonition>
</Accordion>

<MDN title="createElement" url="https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement" />

### 2. `setAttribute()`

`Element.setAttribute` sets a attribute on the current element. 

`setAttribute(name, value)`

`name` - name of the attribute to add. Ex- "type".  
`value` - value of the attribute. Ex- "text".

```js
var ele = document.createElement("input")

ele.setAttribute("type", "text") 
// <input type="text"/>
```
<MDN title="setAttribute" url="https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute" />


### 3. `appendChild()`

`Element.appendChild` inserts a new element as the last child of the current element.

`ele1.appendChild(ele2)`

```js
var eleDiv = document.createElement("div")
var eleH1 = document.createElement("h1")

eleDiv.appendChild(eleH1)
// <div><h1></h1></div>
```

<Accordion title="Related">
  <Admonition type="note" title="If it already has a parent">
  If `ele2` is already a child of another element, 
  then it is first removed from its current parent and then added within the new parent `ele1`.
  </Admonition>

  <Admonition type="note" title="If it is DocumentFragment">
  If `ele2` is a DocumentFragment, then the entire contents of the DocumentFragment is appended 
  to the child list of `ele1`.
  </Admonition>

  <Admonition type="note" title="`.append()`">
  There is a newer api called .append(), which is similar.

  ⭐️ .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 inseting a single element at a time.
  </Admonition>
</Accordion>

<MDN title="appendChild" url="https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild" />