Skip to content

Web APIs

The Web API provides a comprehensive set of interfaces that allow JavaScript to interact with the browser environment, enabling rich user experiences and powerful web applications.

The DOM represents the structure of HTML and XML documents as a tree of objects.

// Select elements
const element = document.getElementById('myId');
const elements = document.querySelectorAll('.className');
const byTag = document.getElementsByTagName('div');
// Create and modify elements
const newDiv = document.createElement('div');
newDiv.textContent = 'Hello, World!';
newDiv.className = 'greeting';
// Insert into document
document.body.appendChild(newDiv);
// Modify existing elements
element.innerHTML = '<strong>Bold text</strong>';
element.style.color = 'blue';
element.setAttribute('data-value', '123');

Events allow JavaScript to respond to user interactions and system events.

// Add event listeners
button.addEventListener('click', (event) => {
console.log('Button clicked!', event);
});
// Event delegation (efficient for dynamic content)
document.addEventListener('click', (event) => {
if (event.target.matches('.dynamic-button')) {
console.log('Dynamic button clicked!');
}
});
// Custom events
const customEvent = new CustomEvent('myEvent', {
detail: { message: 'Hello from custom event!' }
});
element.dispatchEvent(customEvent);
element.addEventListener('myEvent', (event) => {
console.log(event.detail.message);
});

Modern way to make HTTP requests, replacing XMLHttpRequest.

// Basic fetch
fetch('/api/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
// Async/await syntax
async function fetchData() {
try {
const response = await fetch('/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ key: 'value' })
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error('Fetch error:', error);
throw error;
}
}
// AbortController for cancellation
const controller = new AbortController();
const signal = controller.signal;
fetch('/api/slow-endpoint', { signal })
.then(response => response.json())
.catch(error => {
if (error.name === 'AbortError') {
console.log('Request was cancelled');
}
});
// Cancel the request
setTimeout(() => controller.abort(), 5000);

Client-side storage for persisting data.

// localStorage (persists until cleared)
localStorage.setItem('user', JSON.stringify({ name: 'John', age: 30 }));
const user = JSON.parse(localStorage.getItem('user'));
localStorage.removeItem('user');
localStorage.clear(); // Remove all items
// sessionStorage (persists for session)
sessionStorage.setItem('tempData', 'value');
const tempData = sessionStorage.getItem('tempData');
// Storage events (listen for changes in other tabs)
window.addEventListener('storage', (event) => {
console.log('Storage changed:', event.key, event.newValue);
});
// Storage helper class
class StorageManager {
static set(key, value, useSession = false) {
const storage = useSession ? sessionStorage : localStorage;
storage.setItem(key, JSON.stringify(value));
}
static get(key, useSession = false) {
const storage = useSession ? sessionStorage : localStorage;
const item = storage.getItem(key);
return item ? JSON.parse(item) : null;
}
static remove(key, useSession = false) {
const storage = useSession ? sessionStorage : localStorage;
storage.removeItem(key);
}
}

2D graphics and drawing capabilities.

const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Basic shapes
ctx.fillStyle = 'red';
ctx.fillRect(10, 10, 100, 100);
ctx.strokeStyle = 'blue';
ctx.lineWidth = 3;
ctx.strokeRect(50, 50, 100, 100);
// Paths and curves
ctx.beginPath();
ctx.moveTo(200, 50);
ctx.lineTo(250, 100);
ctx.quadraticCurveTo(300, 50, 350, 100);
ctx.stroke();
// Text
ctx.font = '20px Arial';
ctx.fillStyle = 'black';
ctx.fillText('Hello Canvas!', 200, 200);
// Images
const img = new Image();
img.onload = () => {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};
img.src = 'image.jpg';
// Animation
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw animated content here
const time = Date.now() * 0.001;
const x = Math.cos(time) * 100 + 200;
const y = Math.sin(time) * 100 + 200;
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.arc(x, y, 20, 0, Math.PI * 2);
ctx.fill();
requestAnimationFrame(animate);
}
animate();

Access user’s geographical location.

// Check if geolocation is supported
if ('geolocation' in navigator) {
// Get current position
navigator.geolocation.getCurrentPosition(
(position) => {
const { latitude, longitude, accuracy } = position.coords;
console.log(`Lat: ${latitude}, Lon: ${longitude}, Accuracy: ${accuracy}m`);
},
(error) => {
console.error('Geolocation error:', error.message);
},
{
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 60000
}
);
// Watch position changes
const watchId = navigator.geolocation.watchPosition(
(position) => {
updateMap(position.coords.latitude, position.coords.longitude);
},
(error) => {
console.error('Watch position error:', error);
}
);
// Stop watching
navigator.geolocation.clearWatch(watchId);
} else {
console.log('Geolocation not supported');
}

Run JavaScript in background threads.

// Main thread
const worker = new Worker('worker.js');
// Send data to worker
worker.postMessage({ command: 'start', data: [1, 2, 3, 4, 5] });
// Receive messages from worker
worker.onmessage = (event) => {
console.log('Worker result:', event.data);
};
// Handle worker errors
worker.onerror = (error) => {
console.error('Worker error:', error);
};
// Terminate worker
worker.terminate();
worker.js
self.onmessage = (event) => {
const { command, data } = event.data;
if (command === 'start') {
// Perform heavy computation
const result = data.map(x => x * x).reduce((a, b) => a + b, 0);
// Send result back to main thread
self.postMessage({ result });
}
};

Proxy between web app and network, enabling offline functionality.

// Register service worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then((registration) => {
console.log('SW registered:', registration);
})
.catch((error) => {
console.log('SW registration failed:', error);
});
}
// Listen for messages from service worker
navigator.serviceWorker.addEventListener('message', (event) => {
console.log('Message from SW:', event.data);
});
// sw.js - Service Worker
const CACHE_NAME = 'my-cache-v1';
const urlsToCache = [
'/',
'/styles/main.css',
'/scripts/main.js',
'/offline.html'
];
// Install event - cache resources
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => cache.addAll(urlsToCache))
);
});
// Fetch event - serve from cache
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request)
.then((response) => {
// Return cached version or fetch from network
return response || fetch(event.request);
})
);
});

Efficiently observe element visibility changes.

// Create intersection observer
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
console.log('Element is visible:', entry.target);
// Lazy load images
if (entry.target.tagName === 'IMG') {
entry.target.src = entry.target.dataset.src;
observer.unobserve(entry.target);
}
}
});
}, {
root: null, // viewport
rootMargin: '0px',
threshold: 0.1 // 10% visible
});
// Observe elements
document.querySelectorAll('img[data-src]').forEach((img) => {
observer.observe(img);
});
// Infinite scroll example
const sentinel = document.querySelector('#scroll-sentinel');
const scrollObserver = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
loadMoreContent();
}
});
scrollObserver.observe(sentinel);

Display system notifications to users.

// Request permission
async function requestNotificationPermission() {
if ('Notification' in window) {
const permission = await Notification.requestPermission();
return permission === 'granted';
}
return false;
}
// Show notification
function showNotification(title, options = {}) {
if (Notification.permission === 'granted') {
const notification = new Notification(title, {
body: options.body || 'Default body text',
icon: options.icon || '/icon-192x192.png',
badge: options.badge || '/badge-72x72.png',
tag: options.tag || 'default',
data: options.data,
actions: options.actions || []
});
notification.onclick = () => {
console.log('Notification clicked');
window.focus();
notification.close();
};
notification.onclose = () => {
console.log('Notification closed');
};
return notification;
}
}
// Service Worker notifications (for background)
// In service worker:
self.addEventListener('push', (event) => {
const options = {
body: event.data.text(),
icon: '/icon-192x192.png',
badge: '/badge-72x72.png',
actions: [
{ action: 'open', title: 'Open App' },
{ action: 'close', title: 'Close' }
]
};
event.waitUntil(
self.registration.showNotification('Push Notification', options)
);
});

Read and manipulate files selected by users.

// File input handling
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', (event) => {
const files = event.target.files;
for (const file of files) {
console.log('File:', file.name, file.size, file.type);
// Read as text
const reader = new FileReader();
reader.onload = (e) => {
console.log('File content:', e.target.result);
};
reader.readAsText(file);
}
});
// Drag and drop
const dropZone = document.getElementById('dropZone');
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.classList.add('drag-over');
});
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('drag-over');
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.classList.remove('drag-over');
const files = e.dataTransfer.files;
handleFiles(files);
});
function handleFiles(files) {
for (const file of files) {
if (file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = (e) => {
const img = document.createElement('img');
img.src = e.target.result;
img.style.maxWidth = '200px';
document.body.appendChild(img);
};
reader.readAsDataURL(file);
}
}
}

Monitor and optimize web application performance.

// Performance Observer
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
console.log(`${entry.name}: ${entry.duration}ms`);
});
});
observer.observe({ entryTypes: ['measure', 'navigation', 'paint'] });
// Measure custom performance
performance.mark('start-operation');
// ... do some work
performance.mark('end-operation');
performance.measure('operation-duration', 'start-operation', 'end-operation');
// Navigation timing
const navTiming = performance.getEntriesByType('navigation')[0];
console.log('Page load time:', navTiming.loadEventEnd - navTiming.fetchStart);
// Resource timing
const resources = performance.getEntriesByType('resource');
resources.forEach((resource) => {
console.log(`${resource.name}: ${resource.duration}ms`);
});
// Paint timing
const paintEntries = performance.getEntriesByType('paint');
paintEntries.forEach((paint) => {
console.log(`${paint.name}: ${paint.startTime}ms`);
});

Streamlined checkout experience for web payments.

// Check if Payment Request is supported
if ('PaymentRequest' in window) {
const supportedPaymentMethods = [
{
supportedMethods: 'basic-card',
data: {
supportedNetworks: ['visa', 'mastercard', 'amex'],
supportedTypes: ['debit', 'credit']
}
}
];
const paymentDetails = {
total: {
label: 'Total',
amount: { currency: 'USD', value: '25.00' }
},
displayItems: [
{
label: 'Product',
amount: { currency: 'USD', value: '20.00' }
},
{
label: 'Tax',
amount: { currency: 'USD', value: '5.00' }
}
]
};
const options = {
requestPayerName: true,
requestPayerEmail: true,
requestPayerPhone: true,
requestShipping: true
};
// Create payment request
const request = new PaymentRequest(
supportedPaymentMethods,
paymentDetails,
options
);
// Show payment UI
button.addEventListener('click', async () => {
try {
const response = await request.show();
await response.complete('success');
console.log('Payment successful:', response);
} catch (error) {
console.error('Payment failed:', error);
}
});
}

This overview covers the most commonly used Web APIs. Each API has extensive capabilities - explore individual API documentation for complete details and advanced usage patterns.