mirror of
https://github.com/github/awesome-copilot.git
synced 2026-03-12 20:25:11 +00:00
* new skill web-coder * codespellrc: add aNULL HTTPS config cipher string * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestions from code review * Apply suggestion from @jhauga --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
16 KiB
16 KiB
Web APIs & DOM Reference
Comprehensive reference for the Document Object Model (DOM) and Web APIs available in modern browsers.
Document Object Model (DOM)
What is the DOM?
The DOM is a programming interface for HTML and XML documents. It represents the page structure as a tree of objects that can be manipulated with JavaScript.
DOM Tree Structure:
Document
└── html
├── head
│ ├── title
│ └── meta
└── body
├── header
├── main
└── footer
DOM Node Types
| Node Type | Description | Example |
|---|---|---|
| Element | HTML element | <div>, <p> |
| Text | Text content | Text inside elements |
| Comment | HTML comment | <!-- comment --> |
| Document | Root document | document |
| DocumentFragment | Lightweight document | For batch operations |
Selecting Elements
// By ID
const element = document.getElementById('myId');
// By class name (returns HTMLCollection)
const elements = document.getElementsByClassName('myClass');
// By tag name (returns HTMLCollection)
const divs = document.getElementsByTagName('div');
// Query selector (first match)
const first = document.querySelector('.myClass');
const advanced = document.querySelector('div.container > p:first-child');
// Query selector all (returns NodeList)
const all = document.querySelectorAll('.myClass');
// Special selectors
document.body; // Body element
document.head; // Head element
document.documentElement; // <html> element
Traversing the DOM
const element = document.querySelector('#myElement');
// Parent
element.parentElement;
element.parentNode;
// Children
element.children; // HTMLCollection of child elements
element.childNodes; // NodeList of all child nodes
element.firstElementChild;
element.lastElementChild;
// Siblings
element.nextElementSibling;
element.previousElementSibling;
// Closest ancestor matching selector
element.closest('.container');
// Check if element contains another
parent.contains(child); // true/false
Creating and Modifying Elements
// Create element
const div = document.createElement('div');
const text = document.createTextNode('Hello');
const fragment = document.createDocumentFragment();
// Set content
div.textContent = 'Plain text'; // Safe (escaped)
div.innerHTML = '<strong>HTML</strong>'; // Can be unsafe with user input
// Set attributes
div.setAttribute('id', 'myDiv');
div.setAttribute('class', 'container');
div.id = 'myDiv'; // Direct property
div.className = 'container';
div.classList.add('active');
div.classList.remove('inactive');
div.classList.toggle('visible');
div.classList.contains('active'); // true/false
// Set styles
div.style.color = 'red';
div.style.backgroundColor = 'blue';
div.style.cssText = 'color: red; background: blue;';
// Data attributes
div.dataset.userId = '123'; // Sets data-user-id="123"
div.getAttribute('data-user-id'); // "123"
// Insert into DOM
parent.appendChild(div); // Add as last child
parent.insertBefore(div, referenceNode); // Insert before reference
parent.prepend(div); // Add as first child (modern)
parent.append(div); // Add as last child (modern)
element.after(div); // Insert after element
element.before(div); // Insert before element
element.replaceWith(newElement); // Replace element
// Remove from DOM
element.remove(); // Modern way
parent.removeChild(element); // Old way
// Clone element
const clone = element.cloneNode(true); // true = deep clone (with children)
Element Properties
// Dimensions and position
element.offsetWidth; // Width including border
element.offsetHeight; // Height including border
element.clientWidth; // Width excluding border
element.clientHeight; // Height excluding border
element.scrollWidth; // Total scrollable width
element.scrollHeight; // Total scrollable height
element.offsetTop; // Top position relative to offsetParent
element.offsetLeft; // Left position relative to offsetParent
// Bounding box
const rect = element.getBoundingClientRect();
// Returns: { x, y, width, height, top, right, bottom, left }
// Scroll position
element.scrollTop; // Vertical scroll position
element.scrollLeft; // Horizontal scroll position
element.scrollTo(0, 100); // Scroll to position
element.scrollIntoView(); // Scroll element into view
// Check visibility
element.checkVisibility(); // Modern API
Event Handling
Adding Event Listeners
// addEventListener (modern, recommended)
element.addEventListener('click', handleClick);
element.addEventListener('click', handleClick, { once: true }); // Remove after first trigger
function handleClick(event) {
console.log('Clicked!', event);
}
// Event options
element.addEventListener('scroll', handleScroll, {
passive: true, // Won't call preventDefault()
capture: false, // Bubble phase (default)
once: true // Remove after one call
});
// Remove event listener
element.removeEventListener('click', handleClick);
Common Events
| Category | Events |
|---|---|
| Mouse | click, dblclick, mousedown, mouseup, mousemove, mouseenter, mouseleave, contextmenu |
| Keyboard | keydown, keyup, keypress (deprecated) |
| Form | submit, change, input, focus, blur, invalid |
| Window | load, DOMContentLoaded, resize, scroll, beforeunload, unload |
| Touch | touchstart, touchmove, touchend, touchcancel |
| Drag | drag, dragstart, dragend, dragover, drop |
| Media | play, pause, ended, timeupdate, loadeddata |
| Animation | animationstart, animationend, animationiteration |
| Transition | transitionstart, transitionend |
Event Object
element.addEventListener('click', (event) => {
// Target elements
event.target; // Element that triggered event
event.currentTarget; // Element with listener attached
// Mouse position
event.clientX; // X relative to viewport
event.clientY; // Y relative to viewport
event.pageX; // X relative to document
event.pageY; // Y relative to document
// Keyboard
event.key; // 'a', 'Enter', 'ArrowUp'
event.code; // 'KeyA', 'Enter', 'ArrowUp'
event.ctrlKey; // true if Ctrl pressed
event.shiftKey; // true if Shift pressed
event.altKey; // true if Alt pressed
event.metaKey; // true if Meta/Cmd pressed
// Control event flow
event.preventDefault(); // Prevent default action
event.stopPropagation(); // Stop bubbling
event.stopImmediatePropagation(); // Stop other listeners
});
Event Delegation
Handle events on parent instead of individual children:
// Instead of adding listener to each button
document.querySelector('.container').addEventListener('click', (event) => {
if (event.target.matches('button')) {
console.log('Button clicked:', event.target);
}
});
Web Storage APIs
LocalStorage
Persistent storage (no expiration):
// Set item
localStorage.setItem('key', 'value');
localStorage.setItem('user', JSON.stringify({ name: 'John' }));
// Get item
const value = localStorage.getItem('key');
const user = JSON.parse(localStorage.getItem('user'));
// Remove item
localStorage.removeItem('key');
// Clear all
localStorage.clear();
// Get key by index
localStorage.key(0);
// Number of items
localStorage.length;
// Iterate all items
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const value = localStorage.getItem(key);
console.log(key, value);
}
SessionStorage
Storage cleared when tab closes:
// Same API as localStorage
sessionStorage.setItem('key', 'value');
sessionStorage.getItem('key');
sessionStorage.removeItem('key');
sessionStorage.clear();
Storage Limits: ~5-10MB per origin
Fetch API
Modern API for HTTP requests:
// Basic GET request
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
// Async/await
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
// Check if successful
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);
}
}
// POST request with JSON
fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ name: 'John', age: 30 })
})
.then(response => response.json())
.then(data => console.log(data));
// With various options
fetch(url, {
method: 'GET', // GET, POST, PUT, DELETE, etc.
headers: {
'Authorization': 'Bearer token',
'Content-Type': 'application/json'
},
body: JSON.stringify(data), // For POST/PUT
mode: 'cors', // cors, no-cors, same-origin
credentials: 'include', // include, same-origin, omit
cache: 'no-cache', // default, no-cache, reload, force-cache
redirect: 'follow', // follow, error, manual
referrerPolicy: 'no-referrer' // no-referrer, origin, etc.
});
// Response methods
const text = await response.text(); // Plain text
const json = await response.json(); // JSON
const blob = await response.blob(); // Binary data
const arrayBuffer = await response.arrayBuffer(); // ArrayBuffer
const formData = await response.formData(); // FormData
Other Important Web APIs
Console API
console.log('Message'); // Log message
console.error('Error'); // Error message (red)
console.warn('Warning'); // Warning message (yellow)
console.info('Info'); // Info message
console.table([{ a: 1 }, { a: 2 }]); // Table format
console.group('Group'); // Start group
console.groupEnd(); // End group
console.time('timer'); // Start timer
console.timeEnd('timer'); // End timer and log duration
console.clear(); // Clear console
console.assert(condition, 'Error message'); // Assert condition
Timers
// Execute once after delay
const timeoutId = setTimeout(() => {
console.log('Executed after 1 second');
}, 1000);
// Cancel timeout
clearTimeout(timeoutId);
// Execute repeatedly
const intervalId = setInterval(() => {
console.log('Executed every second');
}, 1000);
// Cancel interval
clearInterval(intervalId);
// RequestAnimationFrame (for animations)
function animate() {
// Animation code
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
URL API
const url = new URL('https://example.com:8080/path?query=value#hash');
url.protocol; // 'https:'
url.hostname; // 'example.com'
url.port; // '8080'
url.pathname; // '/path'
url.search; // '?query=value'
url.hash; // '#hash'
url.href; // Full URL
// URL parameters
url.searchParams.get('query'); // 'value'
url.searchParams.set('newParam', 'newValue');
url.searchParams.append('query', 'another');
url.searchParams.delete('query');
url.searchParams.has('query'); // true/false
// Convert to string
url.toString(); // Full URL
FormData API
// Create FormData from form
const form = document.querySelector('form');
const formData = new FormData(form);
// Create FormData manually
const data = new FormData();
data.append('username', 'john');
data.append('file', fileInput.files[0]);
// Get values
data.get('username'); // 'john'
data.getAll('files'); // Array of all 'files' values
// Iterate
for (const [key, value] of data.entries()) {
console.log(key, value);
}
// Send with fetch
fetch('/api/upload', {
method: 'POST',
body: formData // Don't set Content-Type header
});
Intersection Observer API
Detect when element enters viewport:
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
console.log('Element is visible');
entry.target.classList.add('visible');
}
});
}, {
threshold: 0.5, // 50% visible
rootMargin: '0px'
});
observer.observe(element);
observer.unobserve(element);
observer.disconnect(); // Stop observing all
Mutation Observer API
Watch for DOM changes:
const observer = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
console.log('DOM changed:', mutation.type);
});
});
observer.observe(element, {
attributes: true, // Watch attribute changes
childList: true, // Watch child elements
subtree: true, // Watch all descendants
characterData: true // Watch text content
});
observer.disconnect(); // Stop observing
Geolocation API
navigator.geolocation.getCurrentPosition(
(position) => {
console.log(position.coords.latitude);
console.log(position.coords.longitude);
},
(error) => {
console.error('Error getting location:', error);
},
{
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
}
);
// Watch position (continuous updates)
const watchId = navigator.geolocation.watchPosition(callback);
navigator.geolocation.clearWatch(watchId);
Web Workers
Run JavaScript in background thread:
// Main thread
const worker = new Worker('worker.js');
worker.postMessage({ data: 'Hello' });
worker.onmessage = (event) => {
console.log('From worker:', event.data);
};
worker.onerror = (error) => {
console.error('Worker error:', error);
};
worker.terminate(); // Stop worker
// worker.js
self.onmessage = (event) => {
console.log('From main:', event.data);
self.postMessage({ result: 'Done' });
};
Canvas API
Draw graphics:
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
// Draw rectangle
ctx.fillStyle = 'blue';
ctx.fillRect(10, 10, 100, 50);
// Draw circle
ctx.beginPath();
ctx.arc(100, 100, 50, 0, Math.PI * 2);
ctx.fillStyle = 'red';
ctx.fill();
// Draw text
ctx.font = '20px Arial';
ctx.fillText('Hello', 10, 50);
// Draw image
const img = new Image();
img.onload = () => {
ctx.drawImage(img, 0, 0);
};
img.src = 'image.jpg';
IndexedDB
Client-side database for large amounts of structured data:
// Open database
const request = indexedDB.open('MyDatabase', 1);
request.onerror = () => console.error('Database error');
request.onsuccess = (event) => {
const db = event.target.result;
// Use database
};
request.onupgradeneeded = (event) => {
const db = event.target.result;
const objectStore = db.createObjectStore('users', { keyPath: 'id' });
objectStore.createIndex('name', 'name', { unique: false });
};
// Add data
const transaction = db.transaction(['users'], 'readwrite');
const objectStore = transaction.objectStore('users');
objectStore.add({ id: 1, name: 'John' });
// Get data
const request = objectStore.get(1);
request.onsuccess = () => console.log(request.result);
Best Practices
Do's
- ✅ Use
addEventListenerover inline event handlers - ✅ Remove event listeners when no longer needed
- ✅ Use event delegation for dynamic content
- ✅ Cache DOM queries in variables
- ✅ Use
textContentfor plain text (safer thaninnerHTML) - ✅ Use DocumentFragment for batch DOM operations
- ✅ Debounce/throttle scroll and resize handlers
- ✅ Use
requestAnimationFramefor animations - ✅ Validate and sanitize user input
Don'ts
- ❌ Use
innerHTMLwith untrusted data (XSS risk) - ❌ Query DOM repeatedly in loops
- ❌ Modify DOM in tight loops (batch operations)
- ❌ Use
document.write()(deprecated) - ❌ Use synchronous XMLHttpRequest
- ❌ Store sensitive data in localStorage
- ❌ Ignore error handling in async code
- ❌ Block main thread with heavy computations
Glossary Terms
Key Terms Covered:
- API
- Application context
- Beacon
- Blink
- Blink element
- Browser
- Browsing context
- Buffer
- Canvas
- DOM (Document Object Model)
- Document environment
- Event
- Expando
- Global object
- Global scope
- Hoisting
- IndexedDB
- Interpolation
- Node (DOM)
- Shadow tree
- WindowProxy
- Wrapper