Master DOM manipulation, event handling, and modern web APIs for building interactive applications.
Master DOM manipulation, event handling, and modern web APIs for building interactive applications.
Learn the Document Object Model (DOM), how to select elements, and fundamental DOM manipulation methods for creating dynamic web pages
Content by: Fiza Belim
Node.js Developer
The Document Object Model (DOM) is a programming interface for HTML and XML documents. It represents the page so that programs can change the document structure, style, and content. JavaScript can manipulate the DOM to create dynamic and interactive web experiences.
// HTML Structure
<!DOCTYPE html>
<html>
<head>
<title>DOM Example</title>
</head>
<body>
<div id="container">
<h1 id="title">Hello World</h1>
<p class="text">This is a paragraph</p>
<ul id="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</body>
</html>
// DOM Tree Structure
document
āāā html
ā āāā head
ā ā āāā title
ā āāā body
ā āāā div#container
ā āāā h1#title
ā āāā p.text
ā āāā ul#list
ā āāā li
ā āāā li
ā āāā li
// Element selection methods
// 1. getElementById - Select by ID
const title = document.getElementById('title');
console.log(title); // <h1 id="title">Hello World</h1>
// 2. getElementsByClassName - Select by class
const textElements = document.getElementsByClassName('text');
console.log(textElements); // HTMLCollection [p.text]
// 3. getElementsByTagName - Select by tag name
const paragraphs = document.getElementsByTagName('p');
console.log(paragraphs); // HTMLCollection [p.text]
// 4. querySelector - Select first matching element
const firstLi = document.querySelector('li');
const container = document.querySelector('#container');
const textClass = document.querySelector('.text');
// 5. querySelectorAll - Select all matching elements
const allLi = document.querySelectorAll('li');
const allText = document.querySelectorAll('.text');
console.log(allLi.length); // 3
console.log(allText.length); // 1
// 6. Modern selection methods
const container2 = document.querySelector('#container');
const title2 = container2.querySelector('#title'); // Search within container
// 7. Multiple selectors
const elements = document.querySelectorAll('h1, p, li');
console.log(elements.length); // 5 (1 h1 + 1 p + 3 li)
// 8. Attribute selectors
const elementsWithId = document.querySelectorAll('[id]');
const elementsWithClass = document.querySelectorAll('[class]');
const elementsWithData = document.querySelectorAll('[data-*]');
// DOM manipulation examples
// 1. Creating elements
const newDiv = document.createElement('div');
const newParagraph = document.createElement('p');
const newText = document.createTextNode('This is new text');
// 2. Setting content
newParagraph.textContent = 'This is a new paragraph';
newParagraph.innerHTML = '<strong>Bold text</strong> and <em>italic text</em>';
// 3. Setting attributes
newDiv.setAttribute('id', 'new-container');
newDiv.setAttribute('class', 'container new');
newDiv.id = 'new-container'; // Alternative way
newDiv.className = 'container new'; // Alternative way
// 4. Adding elements to DOM
const container = document.getElementById('container');
container.appendChild(newDiv);
container.appendChild(newParagraph);
// 5. Inserting elements
const referenceElement = document.querySelector('p');
container.insertBefore(newParagraph, referenceElement);
// 6. Removing elements
const elementToRemove = document.querySelector('.text');
container.removeChild(elementToRemove);
// 7. Replacing elements
const oldElement = document.querySelector('h1');
const newElement = document.createElement('h2');
newElement.textContent = 'New Title';
container.replaceChild(newElement, oldElement);
// 8. Cloning elements
const originalElement = document.querySelector('li');
const clonedElement = originalElement.cloneNode(true); // true = deep clone
container.appendChild(clonedElement);
// 9. Working with text content
const textElement = document.querySelector('p');
console.log(textElement.textContent); // "This is a paragraph"
console.log(textElement.innerText); // "This is a paragraph"
console.log(textElement.innerHTML); // "This is a paragraph"
// 10. Style manipulation
const styledElement = document.querySelector('h1');
styledElement.style.color = 'red';
styledElement.style.backgroundColor = 'yellow';
styledElement.style.fontSize = '24px';
styledElement.style.margin = '10px 0';
// 11. Class manipulation
const classElement = document.querySelector('div');
classElement.classList.add('highlighted');
classElement.classList.remove('old-class');
classElement.classList.toggle('active');
console.log(classElement.classList.contains('highlighted')); // true
// Exercise: Build a Dynamic Todo List
// HTML structure needed:
/*
<div id="todo-app">
<h1>Todo List</h1>
<div id="todo-input">
<input type="text" id="new-todo" placeholder="Add new todo...">
<button id="add-todo">Add</button>
</div>
<ul id="todo-list"></ul>
</div>
*/
class TodoApp {
constructor() {
this.todos = [];
this.todoInput = document.getElementById('new-todo');
this.addButton = document.getElementById('add-todo');
this.todoList = document.getElementById('todo-list');
this.initializeEventListeners();
}
initializeEventListeners() {
this.addButton.addEventListener('click', () => this.addTodo());
this.todoInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
this.addTodo();
}
});
}
addTodo() {
const text = this.todoInput.value.trim();
if (text) {
const todo = {
id: Date.now(),
text: text,
completed: false
};
this.todos.push(todo);
this.renderTodo(todo);
this.todoInput.value = '';
}
}
renderTodo(todo) {
const li = document.createElement('li');
li.id = `todo-${todo.id}`;
li.className = 'todo-item';
li.innerHTML = `
<input type="checkbox" ${todo.completed ? 'checked' : ''}>
<span class="todo-text">${todo.text}</span>
<button class="delete-btn">Delete</button>
`;
// Add event listeners
const checkbox = li.querySelector('input[type="checkbox"]');
const deleteBtn = li.querySelector('.delete-btn');
const textSpan = li.querySelector('.todo-text');
checkbox.addEventListener('change', () => this.toggleTodo(todo.id));
deleteBtn.addEventListener('click', () => this.deleteTodo(todo.id));
this.todoList.appendChild(li);
}
toggleTodo(id) {
const todo = this.todos.find(t => t.id === id);
if (todo) {
todo.completed = !todo.completed;
const li = document.getElementById(`todo-${id}`);
const textSpan = li.querySelector('.todo-text');
if (todo.completed) {
textSpan.style.textDecoration = 'line-through';
textSpan.style.color = '#888';
} else {
textSpan.style.textDecoration = 'none';
textSpan.style.color = '#000';
}
}
}
deleteTodo(id) {
this.todos = this.todos.filter(t => t.id !== id);
const li = document.getElementById(`todo-${id}`);
if (li) {
li.remove();
}
}
}
// Initialize the app
// const todoApp = new TodoApp();
Test your understanding of this topic:
Master event handling, different event types, event delegation, and modern event patterns for building responsive user interfaces
Content by: Pratik Keshvala
JavaScript Developer
Events are actions or occurrences that happen in the browser, such as clicks, form submissions, or page loads. JavaScript can listen for these events and execute code in response, creating interactive web applications.
// Common event types
// Mouse Events
const button = document.querySelector('button');
button.addEventListener('click', (e) => {
console.log('Button clicked!');
});
button.addEventListener('dblclick', (e) => {
console.log('Button double-clicked!');
});
button.addEventListener('mouseenter', (e) => {
console.log('Mouse entered button');
});
button.addEventListener('mouseleave', (e) => {
console.log('Mouse left button');
});
button.addEventListener('mousedown', (e) => {
console.log('Mouse button pressed');
});
button.addEventListener('mouseup', (e) => {
console.log('Mouse button released');
});
// Keyboard Events
const input = document.querySelector('input');
input.addEventListener('keydown', (e) => {
console.log('Key pressed:', e.key);
});
input.addEventListener('keyup', (e) => {
console.log('Key released:', e.key);
});
input.addEventListener('keypress', (e) => {
console.log('Character typed:', e.key);
});
// Form Events
const form = document.querySelector('form');
form.addEventListener('submit', (e) => {
e.preventDefault(); // Prevent form submission
console.log('Form submitted');
});
form.addEventListener('reset', (e) => {
console.log('Form reset');
});
// Document Events
document.addEventListener('DOMContentLoaded', () => {
console.log('DOM fully loaded');
});
window.addEventListener('load', () => {
console.log('Page fully loaded');
});
window.addEventListener('resize', () => {
console.log('Window resized');
});
window.addEventListener('scroll', () => {
console.log('Page scrolled');
});
// Event object properties
const button = document.querySelector('button');
button.addEventListener('click', (event) => {
// Event target
console.log('Target element:', event.target);
console.log('Current target:', event.currentTarget);
// Mouse position
console.log('Mouse X:', event.clientX);
console.log('Mouse Y:', event.clientY);
console.log('Page X:', event.pageX);
console.log('Page Y:', event.pageY);
// Event type
console.log('Event type:', event.type);
// Timestamp
console.log('Event timestamp:', event.timeStamp);
// Event phase
console.log('Event phase:', event.eventPhase);
// Prevent default behavior
event.preventDefault();
// Stop propagation
event.stopPropagation();
// Stop immediate propagation
event.stopImmediatePropagation();
});
// Keyboard event properties
const input = document.querySelector('input');
input.addEventListener('keydown', (event) => {
console.log('Key:', event.key);
console.log('Code:', event.code);
console.log('Alt key:', event.altKey);
console.log('Ctrl key:', event.ctrlKey);
console.log('Shift key:', event.shiftKey);
console.log('Meta key:', event.metaKey);
// Check for specific keys
if (event.key === 'Enter') {
console.log('Enter key pressed');
}
if (event.ctrlKey && event.key === 's') {
event.preventDefault();
console.log('Save shortcut pressed');
}
});
// Form event properties
const form = document.querySelector('form');
form.addEventListener('submit', (event) => {
event.preventDefault();
const formData = new FormData(event.target);
const data = Object.fromEntries(formData);
console.log('Form data:', data);
});
// Event delegation example
// Instead of adding listeners to each item
const todoList = document.getElementById('todo-list');
// Add listener to parent (event delegation)
todoList.addEventListener('click', (event) => {
const target = event.target;
// Check if clicked element is a delete button
if (target.classList.contains('delete-btn')) {
const todoItem = target.closest('.todo-item');
const todoId = todoItem.dataset.id;
deleteTodo(todoId);
}
// Check if clicked element is a checkbox
if (target.type === 'checkbox') {
const todoItem = target.closest('.todo-item');
const todoId = todoItem.dataset.id;
toggleTodo(todoId, target.checked);
}
});
// Benefits of event delegation
// 1. Fewer event listeners
// 2. Works with dynamically added elements
// 3. Better performance
// 4. Memory efficient
// Example with dynamically added elements
function addTodoItem(text) {
const li = document.createElement('li');
li.className = 'todo-item';
li.dataset.id = Date.now();
li.innerHTML = `
<input type="checkbox">
<span class="todo-text">${text}</span>
<button class="delete-btn">Delete</button>
`;
todoList.appendChild(li);
// No need to add event listeners - delegation handles it!
}
// Event delegation with multiple event types
todoList.addEventListener('click', handleTodoClick);
todoList.addEventListener('mouseenter', handleTodoHover);
todoList.addEventListener('mouseleave', handleTodoLeave);
function handleTodoClick(event) {
const target = event.target;
const todoItem = target.closest('.todo-item');
if (!todoItem) return;
if (target.classList.contains('delete-btn')) {
deleteTodo(todoItem.dataset.id);
} else if (target.type === 'checkbox') {
toggleTodo(todoItem.dataset.id, target.checked);
} else if (target.classList.contains('todo-text')) {
editTodo(todoItem.dataset.id);
}
}
function handleTodoHover(event) {
const todoItem = event.target.closest('.todo-item');
if (todoItem) {
todoItem.classList.add('hovered');
}
}
function handleTodoLeave(event) {
const todoItem = event.target.closest('.todo-item');
if (todoItem) {
todoItem.classList.remove('hovered');
}
}
// Creating and dispatching custom events
// Create custom event
const customEvent = new CustomEvent('todoAdded', {
detail: {
id: 123,
text: 'New todo item',
timestamp: Date.now()
},
bubbles: true,
cancelable: true
});
// Dispatch custom event
document.dispatchEvent(customEvent);
// Listen for custom event
document.addEventListener('todoAdded', (event) => {
console.log('Todo added:', event.detail);
updateTodoCount();
showNotification('Todo added successfully!');
});
// Custom event class
class TodoEvent extends CustomEvent {
constructor(type, todoData) {
super(type, {
detail: todoData,
bubbles: true,
cancelable: true
});
}
}
// Usage
const todoAddedEvent = new TodoEvent('todoAdded', {
id: 456,
text: 'Another todo',
completed: false
});
document.dispatchEvent(todoAddedEvent);
// Event bus pattern
class EventBus {
constructor() {
this.events = {};
}
on(event, callback) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
}
off(event, callback) {
if (this.events[event]) {
this.events[event] = this.events[event].filter(cb => cb !== callback);
}
}
emit(event, data) {
if (this.events[event]) {
this.events[event].forEach(callback => {
callback(data);
});
}
}
}
// Usage
const eventBus = new EventBus();
eventBus.on('todoAdded', (todo) => {
console.log('Todo added via event bus:', todo);
});
eventBus.on('todoDeleted', (todoId) => {
console.log('Todo deleted via event bus:', todoId);
});
eventBus.emit('todoAdded', { id: 789, text: 'Event bus todo' });
eventBus.emit('todoDeleted', 789);
// Exercise: Build an Interactive Color Picker
class ColorPicker {
constructor() {
this.currentColor = '#000000';
this.isDrawing = false;
this.init();
}
init() {
this.createCanvas();
this.createControls();
this.bindEvents();
}
createCanvas() {
const canvas = document.createElement('canvas');
canvas.id = 'drawing-canvas';
canvas.width = 600;
canvas.height = 400;
canvas.style.border = '2px solid #333';
canvas.style.cursor = 'crosshair';
document.body.appendChild(canvas);
this.canvas = canvas;
this.ctx = canvas.getContext('2d');
// Set initial background
this.ctx.fillStyle = '#ffffff';
this.ctx.fillRect(0, 0, canvas.width, canvas.height);
}
createControls() {
const controls = document.createElement('div');
controls.id = 'color-controls';
controls.style.marginBottom = '10px';
controls.innerHTML = `
<input type="color" id="color-picker" value="${this.currentColor}">
<input type="range" id="brush-size" min="1" max="50" value="5">
<span id="brush-size-display">5px</span>
<button id="clear-canvas">Clear Canvas</button>
<button id="save-canvas">Save Image</button>
`;
document.body.insertBefore(controls, this.canvas);
this.colorPicker = document.getElementById('color-picker');
this.brushSize = document.getElementById('brush-size');
this.brushSizeDisplay = document.getElementById('brush-size-display');
}
bindEvents() {
// Color picker events
this.colorPicker.addEventListener('change', (e) => {
this.currentColor = e.target.value;
});
// Brush size events
this.brushSize.addEventListener('input', (e) => {
const size = e.target.value;
this.brushSizeDisplay.textContent = size + 'px';
});
// Canvas events
this.canvas.addEventListener('mousedown', (e) => this.startDrawing(e));
this.canvas.addEventListener('mousemove', (e) => this.draw(e));
this.canvas.addEventListener('mouseup', () => this.stopDrawing());
this.canvas.addEventListener('mouseleave', () => this.stopDrawing());
// Control events
document.getElementById('clear-canvas').addEventListener('click', () => this.clearCanvas());
document.getElementById('save-canvas').addEventListener('click', () => this.saveCanvas());
}
startDrawing(e) {
this.isDrawing = true;
this.draw(e);
}
draw(e) {
if (!this.isDrawing) return;
const rect = this.canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
this.ctx.lineWidth = this.brushSize.value;
this.ctx.lineCap = 'round';
this.ctx.strokeStyle = this.currentColor;
this.ctx.lineTo(x, y);
this.ctx.stroke();
this.ctx.beginPath();
this.ctx.moveTo(x, y);
}
stopDrawing() {
this.isDrawing = false;
this.ctx.beginPath();
}
clearCanvas() {
this.ctx.fillStyle = '#ffffff';
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
}
saveCanvas() {
const link = document.createElement('a');
link.download = 'drawing.png';
link.href = this.canvas.toDataURL();
link.click();
}
}
// Initialize the color picker
// const colorPicker = new ColorPicker();
Test your understanding of this topic:
Learn about the Browser Object Model, window object, location, history, and browser-specific APIs for building cross-browser applications
Content by: Ayush Ladani
React.js Developer
The Browser Object Model (BOM) provides objects and methods for interacting with the browser window and browser-specific features. It includes the window object, location, history, and other browser APIs.
// Window object properties and methods
// Window dimensions
console.log('Window width:', window.innerWidth);
console.log('Window height:', window.innerHeight);
console.log('Screen width:', window.screen.width);
console.log('Screen height:', window.screen.height);
// Window scrolling
window.scrollTo(0, 100); // Scroll to specific position
window.scrollBy(0, 50); // Scroll by specific amount
window.scrollTo({
top: 200,
left: 0,
behavior: 'smooth'
});
// Window opening and closing
const newWindow = window.open('https://example.com', '_blank', 'width=500,height=400');
// newWindow.close(); // Close the window
// Window focus and blur
window.addEventListener('focus', () => {
console.log('Window gained focus');
});
window.addEventListener('blur', () => {
console.log('Window lost focus');
});
// Window resize
window.addEventListener('resize', () => {
console.log('Window resized to:', window.innerWidth, 'x', window.innerHeight);
});
// Window beforeunload
window.addEventListener('beforeunload', (e) => {
e.preventDefault();
e.returnValue = ''; // Show confirmation dialog
});
// Window load
window.addEventListener('load', () => {
console.log('Page fully loaded');
});
// Window online/offline
window.addEventListener('online', () => {
console.log('Browser is online');
});
window.addEventListener('offline', () => {
console.log('Browser is offline');
});
// Location object properties and methods
console.log('Current URL:', window.location.href);
console.log('Protocol:', window.location.protocol);
console.log('Hostname:', window.location.hostname);
console.log('Port:', window.location.port);
console.log('Pathname:', window.location.pathname);
console.log('Search:', window.location.search);
console.log('Hash:', window.location.hash);
// URL parsing
const url = new URL(window.location.href);
console.log('URL object:', url);
console.log('Search params:', url.searchParams);
// Getting query parameters
const searchParams = new URLSearchParams(window.location.search);
const id = searchParams.get('id');
const name = searchParams.get('name');
console.log('ID:', id);
console.log('Name:', name);
// Setting query parameters
searchParams.set('page', '2');
searchParams.set('sort', 'name');
const newUrl = window.location.pathname + '?' + searchParams.toString();
console.log('New URL:', newUrl);
// Navigation methods
// window.location.href = 'https://example.com'; // Navigate to new URL
// window.location.assign('https://example.com'); // Navigate to new URL
// window.location.replace('https://example.com'); // Navigate without adding to history
// window.location.reload(); // Reload current page
// window.location.reload(true); // Force reload from server
// Hash navigation
window.addEventListener('hashchange', () => {
console.log('Hash changed to:', window.location.hash);
});
// Example: Simple router
function handleRoute() {
const hash = window.location.hash.slice(1) || 'home';
switch(hash) {
case 'home':
showHome();
break;
case 'about':
showAbout();
break;
case 'contact':
showContact();
break;
default:
show404();
}
}
window.addEventListener('hashchange', handleRoute);
window.addEventListener('load', handleRoute);
// History object methods
console.log('History length:', window.history.length);
// Navigation methods
// window.history.back(); // Go back one page
// window.history.forward(); // Go forward one page
// window.history.go(-2); // Go back 2 pages
// window.history.go(1); // Go forward 1 page
// History state management
const state = {
page: 'home',
data: { id: 123, name: 'John' }
};
// Push new state
window.history.pushState(state, 'Home Page', '/home');
// Replace current state
window.history.replaceState(state, 'Home Page', '/home');
// Listen for popstate
window.addEventListener('popstate', (event) => {
console.log('State:', event.state);
handleRoute(event.state);
});
// Example: Single Page Application (SPA) router
class SPARouter {
constructor() {
this.routes = {
'/': this.showHome,
'/about': this.showAbout,
'/contact': this.showContact
};
this.init();
}
init() {
window.addEventListener('popstate', (e) => this.handleRoute());
this.handleRoute();
}
navigate(path) {
const state = { path, timestamp: Date.now() };
window.history.pushState(state, '', path);
this.handleRoute();
}
handleRoute() {
const path = window.location.pathname;
const handler = this.routes[path] || this.show404;
handler.call(this);
}
showHome() {
document.getElementById('app').innerHTML = '<h1>Home Page</h1>';
}
showAbout() {
document.getElementById('app').innerHTML = '<h1>About Page</h1>';
}
showContact() {
document.getElementById('app').innerHTML = '<h1>Contact Page</h1>';
}
show404() {
document.getElementById('app').innerHTML = '<h1>404 - Page Not Found</h1>';
}
}
// Usage
// const router = new SPARouter();
// router.navigate('/about');
// Local Storage
// Setting data
localStorage.setItem('user', JSON.stringify({
name: 'John Doe',
email: 'john@example.com',
preferences: {
theme: 'dark',
language: 'en'
}
}));
// Getting data
const user = JSON.parse(localStorage.getItem('user'));
console.log('User:', user);
// Removing data
localStorage.removeItem('user');
// Clearing all data
localStorage.clear();
// Session Storage (similar to localStorage but session-based)
sessionStorage.setItem('sessionId', 'abc123');
const sessionId = sessionStorage.getItem('sessionId');
sessionStorage.removeItem('sessionId');
// Storage events
window.addEventListener('storage', (e) => {
console.log('Storage changed:', e.key);
console.log('Old value:', e.oldValue);
console.log('New value:', e.newValue);
console.log('Storage area:', e.storageArea);
});
// Example: User preferences manager
class UserPreferences {
constructor() {
this.storageKey = 'userPreferences';
this.defaults = {
theme: 'light',
language: 'en',
notifications: true,
autoSave: true
};
this.preferences = this.load();
}
load() {
const stored = localStorage.getItem(this.storageKey);
if (stored) {
return { ...this.defaults, ...JSON.parse(stored) };
}
return { ...this.defaults };
}
save() {
localStorage.setItem(this.storageKey, JSON.stringify(this.preferences));
}
get(key) {
return this.preferences[key];
}
set(key, value) {
this.preferences[key] = value;
this.save();
}
reset() {
this.preferences = { ...this.defaults };
this.save();
}
getAll() {
return { ...this.preferences };
}
}
// Usage
const prefs = new UserPreferences();
prefs.set('theme', 'dark');
prefs.set('language', 'es');
console.log('Theme:', prefs.get('theme'));
console.log('All preferences:', prefs.getAll());
// Exercise: Build a Browser Information Dashboard
class BrowserDashboard {
constructor() {
this.init();
}
init() {
this.createDashboard();
this.updateInfo();
this.bindEvents();
}
createDashboard() {
const dashboard = document.createElement('div');
dashboard.id = 'browser-dashboard';
dashboard.style.cssText = `
position: fixed;
top: 10px;
right: 10px;
background: white;
border: 1px solid #ccc;
padding: 15px;
border-radius: 5px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
font-family: Arial, sans-serif;
font-size: 12px;
max-width: 300px;
`;
dashboard.innerHTML = `
<h3>Browser Info</h3>
<div id="browser-info"></div>
<h3>Window Info</h3>
<div id="window-info"></div>
<h3>Storage Info</h3>
<div id="storage-info"></div>
<button id="refresh-dashboard">Refresh</button>
<button id="clear-storage">Clear Storage</button>
`;
document.body.appendChild(dashboard);
}
updateInfo() {
this.updateBrowserInfo();
this.updateWindowInfo();
this.updateStorageInfo();
}
updateBrowserInfo() {
const info = document.getElementById('browser-info');
info.innerHTML = `
<p><strong>User Agent:</strong> ${navigator.userAgent}</p>
<p><strong>Platform:</strong> ${navigator.platform}</p>
<p><strong>Language:</strong> ${navigator.language}</p>
<p><strong>Online:</strong> ${navigator.onLine ? 'Yes' : 'No'}</p>
<p><strong>Cookies:</strong> ${navigator.cookieEnabled ? 'Enabled' : 'Disabled'}</p>
`;
}
updateWindowInfo() {
const info = document.getElementById('window-info');
info.innerHTML = `
<p><strong>Window Size:</strong> ${window.innerWidth} x ${window.innerHeight}</p>
<p><strong>Screen Size:</strong> ${window.screen.width} x ${window.screen.height}</p>
<p><strong>Scroll Position:</strong> ${window.pageYOffset}px</p>
<p><strong>URL:</strong> ${window.location.href}</p>
<p><strong>History Length:</strong> ${window.history.length}</p>
`;
}
updateStorageInfo() {
const info = document.getElementById('storage-info');
const localStorageSize = this.getStorageSize(localStorage);
const sessionStorageSize = this.getStorageSize(sessionStorage);
info.innerHTML = `
<p><strong>Local Storage:</strong> ${localStorageSize} items</p>
<p><strong>Session Storage:</strong> ${sessionStorageSize} items</p>
<p><strong>Available Storage:</strong> ${this.getAvailableStorage()} MB</p>
`;
}
getStorageSize(storage) {
return Object.keys(storage).length;
}
getAvailableStorage() {
if ('storage' in navigator && 'estimate' in navigator.storage) {
return navigator.storage.estimate().then(estimate => {
return Math.round(estimate.quota / 1024 / 1024);
});
}
return 'Unknown';
}
bindEvents() {
document.getElementById('refresh-dashboard').addEventListener('click', () => {
this.updateInfo();
});
document.getElementById('clear-storage').addEventListener('click', () => {
localStorage.clear();
sessionStorage.clear();
this.updateStorageInfo();
});
// Auto-update on window events
window.addEventListener('resize', () => this.updateWindowInfo());
window.addEventListener('scroll', () => this.updateWindowInfo());
window.addEventListener('online', () => this.updateBrowserInfo());
window.addEventListener('offline', () => this.updateBrowserInfo());
}
}
// Initialize dashboard
// const dashboard = new BrowserDashboard();
Test your understanding of this topic:
Continue your learning journey and master the next set of concepts.
Continue to Module 8