Web APIs: DOM Manipulation and Browser Interaction
Web APIs
JavaScript consists of ECMAScript and Web APIs (DOM, BOM). ECMAScript (ES) provides language standards including variables, data types, expressions, statements, and functions. Browsers implement ES specifications and extend functionality through Web APIs.
DOM Access and Attribute Manipulation
Introduction
- DOM treats every HTML tag as an object with properties and methods for dynamic HTML updates.
- DOM enables dynamic HTML modifications for web effects and user interactions.
- DOM Structure:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document Title</title>
</head>
<body>
Text content
<a href="https://example.com">Link text</a>
<div id="container" class="content">Element content</div>
</body>
</html>
- Document Tree: Hierarchical representation of HTML elements.
- DOM Nodes: Components of the document tree:
- Element Nodes: HTML tags (e.g., div, p, span).
- Attribute Nodes: Tag attributes (e.g., href, id, class).
- Text Nodes: Text content within tags.
- Document Object: Core DOM object with properties and methods for accessing and manipulating elements.
// Document is a built-in object
console.log(typeof document);
// 1. Access root element
console.log(document.documentElement); // Corresponds to html tag
// 2. Access body element
console.log(document.body); // Corresponds to body tag
// 3. Write content to the page
document.write('Hello World!');
Accessing DOM Elements
querySelector(): Retrieves a single element matching a CSS selector.querySelectorAll(): Retrieves multiple elements matching a CSS selector.
<body>
<h3>Finding Element Nodes</h3>
<p>The first step in DOM manipulation is locating elements within the document tree.</p>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
<script>
const firstParagraph = document.querySelector('p');
const allListItems = document.querySelectorAll('li');
</script>
</body>
Element Content Manipulation
innerText: Sets or retrieves text content, treating HTML tags as plain text.innerHTML: Sets or retrieves HTML content, parsing embedded HTML tags.
<body>
<div class="content">Original text content</div>
<script>
const contentElement = document.querySelector('.content');
// Get text content
console.log(contentElement.innerText);
// Set text content (HTML tags will not be rendered)
contentElement.innerText = 'New text content';
contentElement.innerText = '<strong>Bold text</strong>';
// Set HTML content (HTML tags will be rendered)
console.log(contentElement.innerHTML);
contentElement.innerHTML = '<em>Italic text</em>';
</script>
</body>
Element Attribute Manipulation
Common Attribute Modifications
<script>
// 1. Get the DOM element
const imageElement = document.querySelector('.image');
// 2. Modify attributes
imageElement.src = './images/lion.jpg';
imageElement.width = 400;
imageElement.alt = 'Image not available';
</script>
Style Control
- Inline Styles: Direct style property manipulation
<body>
<div class="box"></div>
<script>
const boxElement = document.querySelector('.box');
// Modify style properties
boxElement.style.width = '300px';
// Multi-word properties use camelCase
boxElement.style.backgroundColor = 'pink';
boxElement.style.border = '2px solid blue';
boxElement.style.borderTop = '2px solid red';
</script>
</body>
- Class Name Manipulation: CSS class control
<body>
<div class="navigation">123</div>
<script>
const navElement = document.querySelector('div');
// Add class (className is used because 'class' is a reserved keyword)
navElement.className = 'navigation container';
</script>
</body>
- classList API: Advanced class manipulation
<body>
<div class="box active">Content</div>
<script>
const box = document.querySelector('.box');
// Add class (class names don't include dots and are strings)
box.classList.add('active');
// Remove class
box.classList.remove('box');
// Toggle class (adds if not present, removes if present)
box.classList.toggle('active');
</script>
</body>
Form Element Manipulation
Access: DOMElement.propertyName
Set: DOMElement.propertyName = newValue
<body>
<input type="text" value="Enter text">
<button disabled>Submit</button>
<input type="checkbox" name="agreement" id="agree" class="agree-checkbox">
<script>
// 1. Get elements
const inputElement = document.querySelector('input');
// 2. Get or set values
console.log(inputElement.value);
inputElement.value = 'New value';
inputElement.type = 'password';
// 3. Enable button
const submitButton = document.querySelector('button');
submitButton.disabled = false;
// 4. Check/uncheck checkbox
const checkbox = document.querySelector('.agree-checkbox');
checkbox.checked = true;
</script>
</body>
Custom Attributes
- HTML5 introduced
data-prefixed custom attributes - Accessed through the
datasetproperty in JavaScript
<body>
<div data-id="123">Custom attribute element</div>
<script>
const element = document.querySelector('div');
// Access custom attribute value
console.log(element.dataset.id);
</script>
</body>
Timers (Interval Functions)
Functions that execute code repeatedly at specified intervals
<script>
// 1. Define a function to be repeated
function repeatTask() {
console.log('Executing repeated task...');
}
// 2. Use setInterval to call the function
// Executes every 1000 milliseconds (1 second)
const intervalId = setInterval(repeatTask, 1000);
</script>
DOM Event Fundamentals
Events describe program behaviors or states. When these change, a corresponding function is immediately called.
Event Listening
- Get the DOM element
- Add event listener using
addEventListener - Wait for event trigger (e.g., button click)
- Execute the callback function when triggered
<body>
<button>Click me</button>
<script>
// Requirement: Show alert when button is clicked
const button = document.querySelector('button');
button.addEventListener('click', function() {
alert('Button was clicked!');
});
</script>
</body>
Event Types
Mouse Events
mouseenter: Detects when mouse enters an elementmouseleave: Detects when mouse leaves an element
<body>
<div class="interactive-area"></div>
<script>
const interactiveDiv = document.querySelector('.interactive-area');
// Mouse enter event
interactiveDiv.addEventListener('mouseenter', function() {
console.log('Mouse entered the area');
});
// Mouse leave event
interactiveDiv.addEventListener('mouseleave', function() {
console.log('Mouse left the area');
});
</script>
</body>
Keyboard Events
keydown: Triggered when a key is pressed down: Triggered when a key is released
Focus Events
focus: Element gains focusblur: Element loses focus
Input Events
input: Triggered when user enters text
<body>
<input type="text" placeholder="Type something">
<script>
const inputField = document.querySelector('input');
// Input event
inputField.addEventListener('input', function() {
console.log('Current input value:', inputField.value);
});
</script>
</body>
Event Objects
Event objects contain information about the triggered event. The first parameter in event callback functions is the event object.
<body>
<h3>Event Objects</h3>
<p>When any event is triggered, related information is captured in an object called the event object.</p>
<hr>
<div class="target-area"></div>
<script>
const targetElement = document.querySelector('.target-area');
// Add event listener
targetElement.addEventListener('click', function(event) {
console.log('Event information:', event);
console.log('Target element:', event.target);
console.log('Event type:', event.type);
});
</script>
</body>
Environment Objects
The this keyword refers to the current environment where a function is executing. The general rule is "whoever calls the function, this refers to that caller". When a function is called directly, it's equivalent to window.function(), so this refers to the window object.
<body>
<button>Click me</button>
<script>
const button = document.querySelector('button');
button.addEventListener('click', function() {
// console.log(this) refers to the button element
this.style.backgroundColor = 'blue';
});
// Regular function
function regularFunction() {
console.log(this); // Refers to window object
}
regularFunction();
</script>
</body>
Callback Functions
A callback function is a function passed as an argument to another function.
<script>
// Define function foo
function foo(argument) {
console.log(argument);
}
// Passing primitive values as arguments
foo(10);
foo('Hello world!');
foo(['HTML', 'CSS', 'JavaScript']);
function bar() {
console.log('Function can be a parameter too...');
}
// Functions can also be parameters
foo(bar);
</script>
Advanced DOM Events
Event Flow
The complete execution path of an event, including capture and bubble phases.
Event Capture
Events start from the DOM root element and propagate downward (outer to inner).
// Syntax for event listener with capture phase
element.addEventListener(eventType, handler, true);
Event Bubbling
When an element triggers an event, the event propagates upward through all parent elements with the same event name.
<body>
<div class="parent">
<div class="child"></div>
</div>
<script>
const parentElement = document.querySelector('.parent');
const childElement = document.querySelector('.child');
document.addEventListener('click', function() {
alert('Document clicked');
});
parentElement.addEventListener('click', function() {
alert('Parent clicked');
});
childElement.addEventListener('click', function(event) {
alert('Child clicked');
// Stop event propagation
event.stopPropagation();
});
</script>
</body>
Preventing Default Behavior
Prevents the browser's default action for an event.
// Prevent default event behavior
event.preventDefault();
Event Delegation
Event delegation leverages event bubbling by attaching event listeners to parent elements instead of individual child elements. When a child element is triggered, the event bubbles up to the parent element.
Implementation: Use event.target to identify the actual element that triggered the event.
<body>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<p>This should not change color</p>
</ul>
<script>
// Click each li to change its text color to red
// Use event delegation by attaching listener to parent element
const listElement = document.querySelector('ul');
listElement.addEventListener('click', function(event) {
// Only apply effect to li elements
if (event.target.tagName === 'LI') {
event.target.style.color = 'red';
}
});
</script>
</body>
Other Events
Page Load Events
Triggered when external resources (images, CSS, JavaScript) finish loading.
// Listen for all resources to finish loading
window.addEventListener('load', function() {
// Code to execute after page load
});
Scroll Events
Continuously triggered when the scrollbar is scrolled.
// Listen for scroll events
window.addEventListener('scroll', function() {
// Code to execute during scroll
});
Resize Events
Triggered when the window size changes.
// Listen for window resize events
window.addEventListener('resize', function() {
// Code to execute when window is resized
});
DOM Nodes and Mobile Touch Events
Date Objects
Used to represent time, allowing access to the current system time.
Instantiation
<script>
// Create new Date object
// 1. Get current time
const currentDate = new Date();
console.log(currentDate);
// 2. Specify time
const specificDate = new Date('2024-01-01 08:30:00');
console.log(specificDate);
</script>
Common Date Methods
<script>
// Get date object
const date = new Date();
// Use date methods
console.log(date.getFullYear()); // Year
console.log(date.getMonth() + 1); // Month (0-11, so add 1)
console.log(date.getDate()); // Day of month
console.log(date.getDay()); // Day of week (0-6)
</script>
Timestamps
Milliseconds since January 1, 1970, 00:00:00 UTC. A special way to measure time.
// Three ways to get timestamps
//1. getTime()
const date = new Date();
console.log(date.getTime());
-------------------------------------
//2. Shorthand +new Date()
console.log(+new Date());
-------------------------------------
//3. Date.now()
//Only gets current timestamp, while the first two can return timestamps for specific dates
console.log(Date.now());
Node Operations
Inserting Nodes
<body>
<ul>
<li>First item</li>
</ul>
<script>
const list = document.querySelector('ul');
// Create new element
const newItem = document.createElement('li');
newItem.textContent = 'New item';
// Append as last child
list.appendChild(newItem);
// Insert before specific element
list.insertBefore(newItem, list.children[0]);
</script>
</body>
Removing Nodes
<body>
<button>Remove node</button>
<ul>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
<script>
const removeButton = document.querySelector('button');
removeButton.addEventListener('click', function() {
const list = document.querySelector('ul');
const listItems = document.querySelectorAll('li');
// Remove first item
list.removeChild(listItems[0]);
});
</script>
</body>
Browser Object Model (BOM)
Introduction
The Browser Object Model (BOM) represents the browser's object model. The window object is the global object in JavaScript and the top-level object in the browser. Properties like document, alert(), and console.log() are part of the window object.
Timers - Delayed Functions
setTimeout(): Executes code once after a specified delay.setInterval(): Repeatedly executes code at specified intervals.- Clear timers with
clearTimeout(timerId)orclearInterval(timerId).
<body>
<script>
setTimeout(function() {
console.log('Timer expired');
}, 2000);
</script>
</body>
JavaScript Execution Mechanism
Due to the main thread continuously repeating the cycle of getting tasks, executing tasks, getting more tasks, and executing more, this mechanism is called the event loop.
Location Object
The location object is of type object and splits and saves the various components of a URL address.
<body>
<form action="https://example.com/submit">
<input type="text" name="username">
<input type="password" name="password">
<button>Submit</button>
</form>
<a href="#/profile">Profile</a>
<a href="#/settings">Settings</a>
<a href="#/downloads">Downloads</a>
<button class="refresh-button">Refresh</button>
<script>
console.log(window.location);
console.log(location.href);
// Redirect to another page
// location.href = 'https://newsite.com';
const refreshButton = document.querySelector('.refresh-button');
refreshButton.addEventListener('click', function() {
// Normal refresh
// location.reload();
// Force refresh (Ctrl+F5)
location.reload(true);
});
</script>
</body>
Navigator Object
The navigator object is of type object and records information about the browser itself.
Detect browser version and platform through userAgent:
// Detect userAgent (browser information)
(function() {
const userAgent = navigator.userAgent;
// Check for Android or iPhone
const android = userAgent.match(/(Android);?\s\/\+([\d.]+)?/);
const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/);
// Redirect to mobile site if Android or iPhone
if (android || iphone) {
location.href = 'https://mobile.example.com';
}
})();
History Object
Manages browser history and corresponds to browser address bar operations like forward and back.
<body>
<button>Back</button>
<button>Forward</button>
<script>
const backButton = document.querySelector('button:first-child');
const forwardButton = backButton.nextElementSibling;
backButton.addEventListener('click', function() {
// Go back one page
history.back();
// or history.go(-1);
});
forwardButton.addEventListener('click', function() {
// Go forward one page
history.forward();
// or history.go(1);
});
</script>
</body>
Local Storage
Stores data in the browser locally. Data persists unless manually cleared.
localStorage
- Data persists permanently in the browser.
- Syntax:
// Store data
localStorage.setItem(key, value);
// Retrieve data
localStorage.getItem(key);
// Remove data
localStorage.removeItem(key);
sessionStorage
- Similar to localStorage but data is cleared when the browser tab is closed.
- Syntax:
// Store data
sessionStorage.setItem(key, value);
// Retrieve data
sessionStorage.getItem(key);
// Remove data
sessionStorage.removeItem(key);
Storing Complex Data Types
Challenge: Local storage only supports strings, not complex data types.
Solution: Convert complex data types to JSON strings before storing.
<body>
<script>
const complexData = {
username: 'Developer',
age: 30,
skills: ['JavaScript', 'HTML', 'CSS']
};
// Convert to JSON string before storing
localStorage.setItem('userData', JSON.stringify(complexData));
// Retrieve and parse back to object
const storedData = localStorage.getItem('userData');
const parsedData = JSON.parse(storedData);
console.log(parsedData);
</script>
</body>
Array Methods
map() Method
Iterates over an array, processes each element, and returns a new array.
<body>
<script>
const colors = ['red', 'green', 'blue'];
// Use map to transform array elements
const formattedColors = colors.map(function(item, index) {
return `${item} color`;
});
console.log(formattedColors);
// Output: ['red color', 'green color', 'blue color']
const numbers = [10, 20, 30];
const incrementedNumbers = numbers.map(function(number) {
return number + 5;
});
console.log(incrementedNumbers);
// Output: [15, 25, 35]
</script>
</body>
join() Method
Converts all array elements into a string.
<body>
<script>
const fruits = ['apple', 'banana', 'orange'];
// Join array elements with a separator
const fruitString = fruits.join(', ');
console.log(fruitString);
// Output: "apple, banana, orange"
const emptyString = fruits.join('');
console.log(emptyString);
// Output: "applebananaorange"
</script>
</body>
Regular Expressions
Introduction
Regular expressions are patterns used to match combinations of characters in strings.
Syntax
const regex = /pattern/;
Usage Steps
<body>
<script>
// Basic regular expression usage
const text = 'web development';
// 1. Define pattern
const pattern = /web/;
// 2. Test the pattern
console.log(pattern.test(text)); // true if pattern matches
console.log(pattern.test('programming')); // false if pattern doesn't match
</script>
</body>
Metacharacters
Characters with special meaning that increase flexibility and powerful matching capabilities.
Boundary Characters
Indicate character position:
^: Start of string$: End of string
<body>
<script>
// Boundary characters
const startPattern = /^web/;
console.log(startPattern.test('web development')); // true
console.log(startPattern.test('development web')); // false
const endPattern = /web$/;
console.log(endPattern.test('web development')); // false
console.log(endPattern.test('development web')); // true
// Exact match when ^ and $ are used together
const exactPattern = /^web$/;
console.log(exactPattern.test('web')); // true
console.log(exactPattern.test('web development')); // false
console.log(exactPattern.test('webweb')); // false
</script>
</body>
Quantifiers
Specify how many times a pattern should appear:
*: 0 or more times+: 1 or more times?: 0 or 1 time{n}: Exactly n times{n,}: n or more times{n,m}: Between n and m times (inclusive)
<body>
<script>
// Quantifiers
// * - 0 or more times
const starPattern = /^w*$/;
console.log(starPattern.test('')); // true
console.log(starPattern.test('w')); // true
console.log(starPattern.test('ww')); // true
// + - 1 or more times
const plusPattern = /^w+$/;
console.log(plusPattern.test('')); // false
console.log(plusPattern.test('w')); // true
console.log(plusPattern.test('ww')); // true
// ? - 0 or 1 time
const questionPattern = /^w?$/;
console.log(questionPattern.test('')); // true
console.log(questionPattern.test('w')); // true
console.log(questionPattern.test('ww')); // false
// {n} - exactly n times
const exactPattern = /^w{3}$/;
console.log(exactPattern.test('www')); // true
console.log(exactPattern.test('ww')); // false
// {n,} - n or more times
const minPattern = /^w{2,}$/;
console.log(minPattern.test('ww')); // true
console.log(minPattern.test('w')); // false
// {n,m} - between n and m times
const rangePattern = /^w{2,4}$/;
console.log(rangePattern.test('ww')); // true
console.log(rangePattern.test('www')); // true
console.log(rangePattern.test('wwww')); // true
console.log(rangePattern.test('wwwww')); // false
</script>
</body>
Character Classes
Define character ranges for matching:
// Character classes
. - any character
\d - digit (0-9)\n\D - non-digit\n\w - word character (a-z, A-Z, 0-9, _)\n\W - non-word character\n\s - whitespace\n\S - non-whitespace\n
Replacement and Modifiers
Replacement Syntax
string.replace(/regularExpression/, 'replacementText');
Modifiers
i: Case-insensitive matchingg: Global match (all occurrences)
<body>
<script>
// Replacement and modifiers
const text = 'Welcome to web development. We believe everyone can learn web development.';
// Replace without global modifier (only first occurrence)
const singleReplace = text.replace(/web/, 'Web');
console.log(singleReplace);
// Replace with global modifier (all occurrences)
const globalReplace = text.replace(/web/g, 'Web');
console.log(globalReplace);
// Case-insensitive matching
const caseInsensitive = text.replace(/web/gi, 'WEB');
console.log(caseInsensitive);
</script>
</body>