
Living an open source life!
Hey readers, welcome.. welcome to this article.
If you're somewhere b/w the journey of being a dev , or already are a dev ( i beg your pardon for presuming ) .. You would definitely have heard about Document Object Model.. or shall I say , DOM.
So what is it exactly ? why are you hearing this word here and there..
We'll see that in this article and we'll also see how to manipulate it so that we can say
we know DOM Manipulation ..
So let's step into something that actually makes your webpage alive.
And honestly.. this is where JS starts feeling like a superpower.
PS : One thing that i'll presume for sure that .. You know the Basic JavaScript
What even is the DOM?
Before we touch any method.. let's understand what we're even working with.
You know how a webpage has buttons, text, images, divs everywhere? All of that is written in HTML. But when the browser reads that HTML.. it doesn't just display it. It builds a tree out of it in memory.
That tree is called the DOM .. Document Object Model.
Think of it like a family tree. <html> is the grandparent. Inside it are parents, children, siblings.. all the tags like <div>, <p>, <button>.
And JavaScript can see that tree. It can read it, change it, add to it, remove from it. That's DOM manipulation.
Okay now let's go through every method one by one.
1. document.createElement(tag)
Makes a brand new HTML element. Like building a new LEGO brick.. it exists but isn't placed anywhere yet.
const box = document.createElement('div');
// you just made a <div>.. floating in memory, not on the page yet
This is the most used method in all of DOM. Every time you want to add something new to the page.. you start here.
2. element.appendChild(child)
Puts a child element INSIDE a parent. Like dropping a toy into a box.
const menuBoard = document.createElement('div');
const sweetItem = document.createElement('div');
menuBoard.appendChild(sweetItem);
// now sweetItem is inside menuBoard
// <div>
// <div></div>
// </div>
createElement makes the brick.. appendChild places it.
3. element.append(...nodes)
Same as appendChild but you can pass multiple things at once.
const card = document.createElement('div');
const img = document.createElement('img');
const h3 = document.createElement('h3');
const p = document.createElement('p');
card.append(img, h3, p);
// all three added in one line
4. element.textContent
Sets or reads the text inside an element.
const h3 = document.createElement('h3');
h3.textContent = 'Rasgulla';
// <h3>Rasgulla</h3>
console.log(h3.textContent); // "Rasgulla"
Like writing on a sticky note that's inside a box.
5. element.innerText
Similar to textContent but it's layout-aware.. it only returns text that's actually visible on the page.
const p = document.createElement('p');
p.innerHTML = 'Hello <span style="display:none">hidden</span> World';
p.innerText; // "Hello World" (hidden text is excluded)
p.textContent; // "Hello hidden World" (returns everything)
Also, reading innerText triggers a reflow (browser recalculates layout) so it's slightly slower than textContent. For just setting text, both work the same.
const h3 = document.createElement('h3');
h3.innerText = 'Rasgulla';
// <h3>Rasgulla</h3>
textContent vs innerText vs innerHTML
All three let you read/write content inside an element.. but they behave very differently.
textContent |
innerText |
innerHTML |
|
|---|---|---|---|
| Returns | Raw text, all of it | Only visible text | Raw HTML string |
| Hidden elements | Included | Excluded | Included |
| HTML tags | Stripped (returns text only) | Stripped | Preserved |
| Setting it | Treats input as plain text (safe) | Treats input as plain text (safe) | Parses input as HTML ( ️ XSS risk) |
| Performance | Fast | Slower (triggers reflow) | Medium |
div.innerHTML = '<b>Hello</b> <span style="display:none">secret</span>';
div.textContent; // "Hello secret" — all text, no tags
div.innerText; // "Hello" — only visible text
div.innerHTML; // "<b>Hello</b> <span style="display:none">secret</span>"
6. element.innerHTML
Sets or reads the raw HTML inside an element. Setting it replaces everything inside.
container.innerHTML = ''; // clears all children instantly
div.innerHTML = '<h3>Hello</h3><p>World</p>';
// creates and inserts those elements at once
Useful for clearing a container before re-rendering.. or building quick HTML strings.
7. element.setAttribute(name, value)
Sets any attribute on an element.
const div = document.createElement('div');
div.setAttribute('id', 'menu-board');
// <div id="menu-board"></div>
8. element.classList.add('name')
Adds a CSS class to an element. Like putting a sticker on something.
const div = document.createElement('div');
div.classList.add('sweet-item');
// <div class="sweet-item"></div>
9. element.classList.remove('name')
Removes a class. Like peeling off that sticker.
div.classList.remove('sweet-item');
// <div></div>
10. element.classList.toggle('name')
If the class is there.. removes it. If it's not.. adds it. Like a light switch.
div.classList.toggle('active'); // adds "active"
div.classList.toggle('active'); // removes "active"
div.classList.toggle('active'); // adds again
11. element.classList.contains('name')
Checks if an element has a class. Returns true or false.
div.classList.add('waiting');
div.classList.contains('waiting'); // true
div.classList.contains('serving'); // false
12. element.dataset
Lets you store and read custom data on an element using data-* attributes.
const div = document.createElement('div');
div.dataset.zone = 'North';
div.dataset.rating = 4.5;
// <div data-zone="North" data-rating="4.5"></div>
console.log(div.dataset.zone); // "North"
console.log(Number(div.dataset.rating)); // 4.5
Think of it like writing notes on the back of a toy.. "this belongs to North zone, rating 4.5".
One thing to remember.. dataset values are always strings. So if you stored a number, use Number() to convert it back.
13. element.style.propertyName
Sets inline CSS styles directly on an element. Use camelCase.. not kebab-case.
const div = document.createElement('div');
div.style.backgroundColor = 'brown'; // not "background-color"
div.style.width = '100px';
div.style.borderRadius = '50%';
14. document.getElementById('id')
Finds ONE element by its exact id. Super fast, super direct.
// HTML: <p id="price-masala">Rs.15</p>
const el = document.getElementById('price-masala');
el.textContent = 'Rs.20';
15. element.querySelector('selector')
Finds the first element matching a CSS selector inside element (or document).
const stallName = document.querySelector('.stall-name');
// returns the first element with class "stall-name"
16. element.querySelectorAll('selector')
Finds ALL elements matching a CSS selector. Returns a NodeList.. which looks like an array but isn't quite one.
const allPrices = document.querySelectorAll('.chai-price');
// every element with class "chai-price"
17. Array.from(nodeList)
Converts a NodeList into a real JavaScript array so you can use .filter(), .map(), .forEach() on it.
const items = Array.from(document.querySelectorAll('.chai-price'));
items.filter(el => Number(el.textContent.replace('Rs.', '')) < 15);
18. element.addEventListener(event, handler)
Attaches a function to run when something happens.. click, submit, keypress, anything.
const btn = document.createElement('button');
btn.addEventListener('click', () => {
console.log('clicked!');
});
This is how your page becomes interactive. Without this.. everything is just static.
19. element.removeEventListener(event, handler)
Removes a previously added event listener. You MUST pass the same function reference.. not a new one.
const handler = () => console.log('clicked');
btn.addEventListener('click', handler);
// later..
btn.removeEventListener('click', handler); // gone
This is why we store the handler in a variable. So we can remove it later when we don't need it anymore.
20. event.preventDefault()
Stops the browser's default behavior. Most important use.. stopping a form from reloading the page on submit.
form.addEventListener('submit', (e) => {
e.preventDefault(); // page won't reload
// now do your own validation
});
Without this.. every form submit would refresh the page and you'd lose everything.
21. event.target
Inside an event listener, event.target is the exact element that was clicked or interacted with.
container.addEventListener('click', (e) => {
console.log(e.target); // the thing that was actually clicked
});
22. event.target.closest('selector')
Starts from the clicked element and walks UP the DOM tree until it finds an ancestor matching the selector.
// HTML:
// <div class="guest-item">
// <span>Rahul</span>
// <button class="remove-btn">Remove</button>
// </div>
container.addEventListener('click', (e) => {
const btn = e.target.closest('.remove-btn');
if (btn) {
btn.closest('.guest-item').remove();
}
});
This is the heart of event delegation.. one listener handles clicks on many children. Instead of adding a listener to every button, you add one to the parent and let clicks bubble up.
23. element.closest('selector')
Same idea but called on any element, not just event.target. Walks up the tree to find the nearest matching ancestor (or itself).
const btn = document.getElementById('myBtn');
btn.closest('.queue-container');
// finds the nearest .queue-container above btn
24. element.parentNode
Gives you the direct parent of an element.
// <div class="queue-container">
// <div class="queue-item">Auto 1</div>
// </div>
const item = document.querySelector('.queue-item');
item.parentNode; // the .queue-container div
25. element.nextElementSibling
Gives you the next element sitting right beside this one (same parent). Like asking "who's standing after me in line?"
// <div id="a">Auto 1</div>
// <div id="b">Auto 2</div>
// <div id="c">Auto 3</div>
document.getElementById('a').nextElementSibling;
// <div id="b">Auto 2</div>
26. element.previousElementSibling
Same but the one BEFORE you.
document.getElementById('c').previousElementSibling;
// <div id="b">Auto 2</div>
27. element.children
Gives you ALL direct children of an element as an HTMLCollection.
const container = document.querySelector('.queue-container');
Array.from(container.children);
// [<div>Auto 1</div>, <div>Auto 2</div>, <div>Auto 3</div>]
28. element.firstElementChild
Gets the first child element. Always safe to use because it ignores text nodes and whitespace.
parent.firstElementChild; // first <div>, <p>, etc. inside parent
Prefer this over firstChild.. firstChild can return invisible text nodes and cause weird bugs.
29. element.lastChild
Gets the very last child node. Used when you want to remove the last item from a list.
if (thali.lastChild) {
thali.removeChild(thali.lastChild);
}
30. parentNode.insertBefore(newNode, referenceNode)
Inserts newNode BEFORE referenceNode inside the parent. Like cutting in line.
// Before: [Auto1, Auto2, Auto3]
parent.insertBefore(auto3, auto1);
// After: [Auto3, Auto1, Auto2]
If referenceNode is null.. it just appends at the end. Same as appendChild.
31. parentNode.removeChild(child)
Removes a child from its parent and returns the removed element.
const removed = parent.removeChild(auto2);
// auto2 is gone from the DOM.. but you still have it in `removed`
32. parentNode.replaceChild(newChild, oldChild)
Swaps out an old child for a new one. Returns the old (removed) child.
const old = stage.replaceChild(newDancer, oldDancer);
// newDancer is now in the DOM, oldDancer is returned
33. element.cloneNode(deep)
Makes a copy of an element.
cloneNode(true).. deep copy, copies the element AND everything inside itcloneNode(false).. shallow copy, copies only the element, not its children
const original = document.getElementById('dancer1');
// <div id="dancer1" class="dancer">Priya</div>
const copy = original.cloneNode(true);
copy.id = 'dancer1-copy';
// <div id="dancer1-copy" class="dancer">Priya</div>
Like photocopying a page. Deep copy = copies the writing too. Shallow = just the blank page shape.
34. element.remove()
Removes an element from the DOM directly. No need to go through the parent.
const item = document.querySelector('.guest-item');
item.remove(); // gone
35. element.contentEditable
Makes an element editable by the user.. like a text box but for any element.
el.contentEditable = 'true'; // user can now type in it
el.contentEditable = 'false'; // back to read-only
36. formElement.elements
Gives you access to all inputs inside a form by their name attribute.
// <form>
// <input name="name" value="Rahul" />
// <input name="date" value="2025-12-25" />
// </form>
form.elements.name.value; // "Rahul"
form.elements.date.value; // "2025-12-25"
Array methods you'll use constantly with DOM
These aren't DOM methods but you'll use them with DOM all the time.. so let's cover them here.
array.filter(fn)
Returns a new array with only the items where fn returns true.
const redKites = kites.filter(k => k.color === 'Red');
array.sort(fn)
Sorts an array in place. Pass a compare function for custom order.
pandals.sort((a, b) => Number(b.dataset.rating) - Number(a.dataset.rating));
// highest rating first
array.forEach(fn)
Runs a function for each item. Doesn't return anything.
sweets.forEach(sweet => {
const item = createSweetItem(sweet.name, sweet.price, sweet.category);
menuBoard.appendChild(item);
});
array.map(fn)
Returns a NEW array by transforming each item.
const guestData = [...container.querySelectorAll('.guest-item')].map(el => ({
name: el.dataset.name,
side: el.dataset.side
}));
array.find(fn)
Returns the first item where fn returns true.
const priya = guests.find(g => g.dataset.name === 'Priya');
array.reduce(fn)
Reduces an array to a single value.
const cheapest = allPrices.reduce((min, el) => {
const price = Number(el.textContent.replace('Rs.', ''));
const minPrice = Number(min.textContent.replace('Rs.', ''));
return price < minPrice ? el : min;
});
[...spread]
Copies an array without mutating the original.
const sorted = [...kites].sort(...);
// kites is untouched, sorted is a new array
Quick Cheat Sheet
| Method | What it does |
|---|---|
createElement(tag) |
Make a new element |
appendChild(child) |
Put child inside parent |
append(...nodes) |
Put multiple children inside parent |
textContent |
Set/get all text (including hidden) |
innerText |
Set/get only visible text |
innerHTML |
Set/get raw HTML inside element |
setAttribute(k, v) |
Set any attribute |
classList.add/remove/toggle/contains |
Manage CSS classes |
dataset.key |
Read/write data-* attributes |
style.propertyName |
Set inline CSS |
getElementById('id') |
Find element by id |
querySelector('sel') |
Find first matching element |
querySelectorAll('sel') |
Find all matching elements |
closest('sel') |
Walk up tree, find ancestor |
parentNode |
Get direct parent |
nextElementSibling |
Get next sibling |
previousElementSibling |
Get previous sibling |
children |
Get all direct children |
firstElementChild |
First element child (safe) |
lastChild |
Last child node |
insertBefore(new, ref) |
Insert before a reference node |
removeChild(child) |
Remove a child, get it back |
replaceChild(new, old) |
Swap one child for another |
cloneNode(deep) |
Copy an element |
remove() |
Remove element directly |
addEventListener(ev, fn) |
Listen for events |
removeEventListener(ev, fn) |
Stop listening |
event.preventDefault() |
Stop default browser behavior |
event.target |
What was actually clicked |
event.target.closest('sel') |
Walk up from click target |
contentEditable |
Make element editable |
formElement.elements |
Access form inputs by name |
Array.from(nodeList) |
Convert NodeList to array |
[...spread] |
Copy an array |
array.filter(fn) |
Keep items matching condition |
array.sort(fn) |
Sort array |
array.forEach(fn) |
Loop through array |
array.map(fn) |
Transform array into new array |
array.find(fn) |
Find first matching item |
array.reduce(fn) |
Reduce array to single value |
Alright.. that's it for today. That's basic DOM methods that we've discussed.
Do Practice , It on your own .. try making something out of it.. so that you'll understand it better..
Summary :
The DOM is just a family tree of HTML elements, and JavaScript gives you the tools to read it, change it, move things around, and react to what the user does. Once this clicks.. you'll start seeing every webpage differently.
See you in the next one..




