Real DOM
What is the Real DOM?
The Document Object Model (DOM) is a programming interface for HTML documents. It represents the page as a tree of objects that can be manipulated with JavaScript.
Try DOM Manipulation
Code Editor
Console Output
Click "Run" to execute your code...
Example 1: Selecting DOM Elements
// getElementById - returns single element
const header = document.getElementById('header');
console.log(header);
// getElementsByClassName - returns HTMLCollection (live)
const items = document.getElementsByClassName('item');
console.log(items); // HTMLCollection
console.log(items.length);
// getElementsByTagName - returns HTMLCollection
const paragraphs = document.getElementsByTagName('p');
console.log(paragraphs);
// querySelector - returns first matching element
const firstItem = document.querySelector('.item');
const button = document.querySelector('#submit-btn');
const input = document.querySelector('input[type="text"]');
// querySelectorAll - returns NodeList (static)
const allItems = document.querySelectorAll('.item');
allItems.forEach(item => {
console.log(item.textContent);
});
// Difference: HTMLCollection vs NodeList
// HTMLCollection: live, auto-updates when DOM changes
// NodeList from querySelectorAll: static snapshot
// Parent-child relationships
const parent = document.getElementById('parent');
const children = parent.children; // HTMLCollection
const childNodes = parent.childNodes; // NodeList (includes text nodes)
const firstChild = parent.firstElementChild;
const lastChild = parent.lastElementChild;
// Siblings
const element = document.querySelector('.item');
const next = element.nextElementSibling;
const prev = element.previousElementSibling;
// Parent
const parentEl = element.parentElement;
const closest = element.closest('.container'); // Finds closest ancestorExample 2: Creating and Modifying Elements
// Creating elements
const div = document.createElement('div');
const text = document.createTextNode('Hello World');
const fragment = document.createDocumentFragment(); // For batch operations
// Setting content
div.textContent = 'Plain text (safe from XSS)';
div.innerHTML = '<span>HTML content (be careful!)</span>';
// Setting attributes
div.id = 'myDiv';
div.className = 'container';
div.setAttribute('data-id', '123');
div.setAttribute('role', 'button');
// Getting attributes
const id = div.id;
const dataId = div.getAttribute('data-id');
const hasRole = div.hasAttribute('role');
// Removing attributes
div.removeAttribute('role');
// Working with classes
div.classList.add('active');
div.classList.remove('inactive');
div.classList.toggle('visible');
div.classList.contains('active'); // true
div.classList.replace('old-class', 'new-class');
// Styles
div.style.color = 'red';
div.style.backgroundColor = 'blue';
div.style.fontSize = '16px';
// Better: use CSS classes instead of inline styles
// div.classList.add('styled');
// Data attributes
div.dataset.userId = '456';
div.dataset.userName = 'John';
console.log(div.dataset.userId); // '456'
// Adding to DOM
const container = document.getElementById('container');
container.appendChild(div);
container.insertBefore(div, container.firstChild);
container.replaceChild(newElement, oldElement);
// Modern methods
container.append(div, 'text', otherElement); // Can add multiple
container.prepend(div); // Add to beginning
container.before(div); // Add before element
container.after(div); // Add after element
div.replaceWith(newElement); // Replace element
div.remove(); // Remove from DOMExample 3: DOM Manipulation Examples
// Example 1: Creating a list dynamically
function createList(items) {
const ul = document.createElement('ul');
ul.className = 'item-list';
items.forEach(item => {
const li = document.createElement('li');
li.textContent = item;
li.className = 'list-item';
ul.appendChild(li);
});
return ul;
}
const fruits = ['Apple', 'Banana', 'Orange'];
const list = createList(fruits);
// document.body.appendChild(list);
// Example 2: Creating a card component
function createCard(title, description, imageUrl) {
const card = document.createElement('div');
card.className = 'card';
card.innerHTML = `
<img src="${imageUrl}" alt="${title}" class="card-image">
<div class="card-body">
<h3 class="card-title">${title}</h3>
<p class="card-description">${description}</p>
<button class="btn btn-primary">Learn More</button>
</div>
`;
return card;
}
const card = createCard(
'JavaScript',
'Learn JavaScript fundamentals',
'/images/js.png'
);
// Example 3: Table generation
function createTable(data) {
const table = document.createElement('table');
table.className = 'data-table';
// Create header
const thead = document.createElement('thead');
const headerRow = document.createElement('tr');
Object.keys(data[0]).forEach(key => {
const th = document.createElement('th');
th.textContent = key;
headerRow.appendChild(th);
});
thead.appendChild(headerRow);
table.appendChild(thead);
// Create body
const tbody = document.createElement('tbody');
data.forEach(row => {
const tr = document.createElement('tr');
Object.values(row).forEach(value => {
const td = document.createElement('td');
td.textContent = value;
tr.appendChild(td);
});
tbody.appendChild(tr);
});
table.appendChild(tbody);
return table;
}
const users = [
{ name: 'John', age: 30, city: 'New York' },
{ name: 'Jane', age: 25, city: 'London' }
];
const table = createTable(users);Example 4: Performance Optimization
// Bad: Multiple reflows (slow)
const container = document.getElementById('container');
for (let i = 0; i < 1000; i++) {
const div = document.createElement('div');
div.textContent = `Item ${i}`;
container.appendChild(div); // Triggers reflow each time!
}
// Good: Use DocumentFragment (fast)
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
const div = document.createElement('div');
div.textContent = `Item ${i}`;
fragment.appendChild(div);
}
container.appendChild(fragment); // Single reflow!
// Better: Build HTML string (fastest for simple cases)
let html = '';
for (let i = 0; i < 1000; i++) {
html += `<div>Item ${i}</div>`;
}
container.innerHTML = html;
// Batch DOM reads and writes
// Bad: Interleaving reads and writes
const elements = document.querySelectorAll('.item');
elements.forEach(el => {
const height = el.clientHeight; // Read (forces layout)
el.style.height = height * 2 + 'px'; // Write
});
// Good: Batch reads, then batch writes
const elements = document.querySelectorAll('.item');
const heights = Array.from(elements).map(el => el.clientHeight);
elements.forEach((el, i) => {
el.style.height = heights[i] * 2 + 'px';
});
// Use classList instead of className
// Bad: Triggers reflow
element.className = 'class1 class2 class3';
// Good: Batched internally
element.classList.add('class1', 'class2', 'class3');
// Detach element before multiple modifications
const list = document.getElementById('list');
const parent = list.parentNode;
parent.removeChild(list);
// Make modifications
list.classList.add('modified');
list.style.color = 'red';
// ... many more changes
// Reattach
parent.appendChild(list);Example 5: DOM Properties and Methods
// Element dimensions and position
const element = document.querySelector('.box');
// Size (including padding, excluding border)
console.log(element.clientWidth);
console.log(element.clientHeight);
// Size (including padding and border)
console.log(element.offsetWidth);
console.log(element.offsetHeight);
// Size (including padding, border, and scrollbar)
console.log(element.scrollWidth);
console.log(element.scrollHeight);
// Position relative to offsetParent
console.log(element.offsetLeft);
console.log(element.offsetTop);
// Precise position and size
const rect = element.getBoundingClientRect();
console.log(rect.top, rect.left, rect.width, rect.height);
// Scroll position
console.log(element.scrollTop);
console.log(element.scrollLeft);
element.scrollTop = 100; // Scroll to position
// Scroll to element
element.scrollIntoView({ behavior: 'smooth', block: 'center' });
// Clone element
const clone = element.cloneNode(true); // true = deep clone (with children)
const shallowClone = element.cloneNode(false);
// Check if element contains another
const container = document.getElementById('container');
const child = document.querySelector('.child');
console.log(container.contains(child)); // true
// Check if elements match selector
console.log(element.matches('.box')); // true
console.log(element.matches('#myId')); // false
// Comparing nodes
const el1 = document.getElementById('el1');
const el2 = document.getElementById('el2');
console.log(el1.isEqualNode(el2)); // Same structure and content?
console.log(el1.isSameNode(el2)); // Same object reference?
// Focus management
const input = document.querySelector('input');
input.focus();
input.blur();
console.log(document.activeElement); // Currently focused elementKey Points
- DOM is a tree structure representing HTML document
- Use querySelector/querySelectorAll for flexible element selection
- Minimize DOM manipulations - batch operations when possible
- Use DocumentFragment for adding multiple elements
- classList is better than className for class management
- Avoid layout thrashing (interleaved reads and writes)
- Real DOM operations are expensive - Virtual DOM helps optimize