Files
UiQuestions/docs/create-modify-element.mdx
T

237 lines
6.6 KiB
Plaintext

---
id: create-modify-element
# 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);
// <div className="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
### 3. createElement()
It creates a new HTML element, taking the tag name (`"div"`) as argument.
```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" />
### 4. setAttribute()
It sets a attribute on the current element.
`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" />
### 5. appendChild()
It inserts a new element as the last child of the parent element.
`Element.appendChild(newElement)`
```js
var eleDiv = document.createElement("div")
var eleH1 = document.createElement("h1")
eleDiv.appendChild(eleH1)
// <div><h1></h1></div>
```
<Accordion title="Edge cases and alternative">
<Admonition type="note" title="If it already has a parent">
If newElement is already a child of another element,
then it is removed from its existing parent and then added to the new parent.
</Admonition>
<Admonition type="note" title="If it is DocumentFragment">
If newElement 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 element.
</Admonition>
<Admonition type="note" title=".append()">
There is a newer api called .append(), which is a superset of .appendChild().<br/><br/>
⭐️ .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.
</Admonition>
</Accordion>
<MDN title="appendChild" url="https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild" />
### 6. removeChild()
`Element.removeChild(childElement)`
This method tries to remove a child element from the parent and returns the removed node.
If the element to be removed is not a child of the parent element, it throws a `NotFoundError` DOMException.
```js
// <div class="parent">
// <div class="child"/>
// </div>
parentEle.removeChild(childEle)
```
<MDN title="removeChild" url="https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild" />
### 7. insertBefore()
`Element.insertBefore(newEle, refEle)`
This method inserts a new child element before another child within a parent.
`newEle` - The node to be inserted.
`refEle` - The reference element before which newEle should be inserted. If refEle is `null`, then newEle is added as the last child.
```js
// <ul>
// <li> Apple </li>
// <li> Zebra </li>
// </ul>
// To add a new <li> above "Zebra"
var parent = document.querySelector("ul")
var ref = document.querySelector("li:last-child")
var 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)
```
:::
<MDN title="insertBefore" url="https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore" />
### 8. 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).
**Methods** -
`document.createDocumentFragment()` - creates a new empty fragment.
`.appendChild()` / `.insertBefore()` - can be used to move the whole content of the fragment to the actual DOM.
**Example** -
```js
var fragment = document.createDocumentFragment()
// Insert / modify elements in fragment
// in dom, <div class="outer"/>
var outerEle = document.querySelector(".outer")
outerEle.appendChild(fragment)
// This will remove all content from fragment and
// insert them within outerEle.
```
<MDN title="Document Fragment" url="https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment" />
--------
In the next section, we'll see how to read information from a DOM element.