什么是Web APIs?
Web APIs是浏览器提供的编程接口,允许JavaScript与浏览器功能和用户环境进行交互。这些API扩展了JavaScript的能力,使其能够操作DOM、发送网络请求、访问设备功能等。
Web APIs的重要性: Web APIs是构建现代Web应用的基础,它们提供了访问浏览器功能、设备硬件和操作系统的能力,使Web应用能够提供类似原生应用的体验。
Web APIs的分类
- 文档对象模型(DOM) API - 操作HTML和XML文档
- 网络API - 发送网络请求和处理响应
- 存储API - 在客户端存储数据
- 设备API - 访问设备硬件和传感器
- 多媒体API - 处理音频、视频和图形
- 通信API - 实现客户端与服务器之间的实时通信
- 性能API - 监控和优化应用性能
DOM API
文档对象模型API允许JavaScript操作HTML和XML文档的内容、结构和样式。
DOM树结构
DOM将HTML文档表示为节点树,每个节点代表文档中的一个部分(元素、属性、文本等)。
DOM操作示例
// 选择元素
const element = document.getElementById('myId');
const elements = document.querySelectorAll('.myClass');
// 创建和添加元素
const newDiv = document.createElement('div');
newDiv.textContent = '新创建的元素';
newDiv.className = 'new-element';
document.body.appendChild(newDiv);
// 修改样式
element.style.color = 'red';
element.style.fontSize = '16px';
// 添加事件监听器
element.addEventListener('click', function() {
console.log('元素被点击了');
});
// 操作类名
element.classList.add('active');
element.classList.remove('inactive');
element.classList.toggle('visible');
// 获取和设置属性
const value = element.getAttribute('data-custom');
element.setAttribute('data-custom', 'new-value');
DOM事件处理
DOM事件处理是Web开发中的重要部分,允许响应用户交互。
事件处理示例
// 事件委托
document.getElementById('parent').addEventListener('click', function(e) {
if (e.target && e.target.matches('button.item')) {
console.log('按钮被点击:', e.target.textContent);
}
});
// 自定义事件
const customEvent = new CustomEvent('myEvent', {
detail: { message: '自定义事件数据' }
});
element.dispatchEvent(customEvent);
// 事件对象属性
element.addEventListener('click', function(e) {
console.log('事件类型:', e.type);
console.log('目标元素:', e.target);
console.log('当前目标:', e.currentTarget);
console.log('事件阶段:', e.eventPhase);
});
Fetch API
Fetch API提供了现代化的网络请求接口,用于替代传统的XMLHttpRequest。
Fetch API的优势
- 基于Promise,避免回调地狱
- 更简洁的API设计
- 更好的错误处理机制
- 支持流式处理和取消请求
Fetch API使用示例
// 基本的GET请求
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) {
throw new Error('网络响应不正常');
}
return response.json();
})
.then(data => {
console.log('获取的数据:', data);
})
.catch(error => {
console.error('请求失败:', error);
});
// POST请求
fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token123'
},
body: JSON.stringify({
name: '张三',
email: 'zhang@example.com'
})
})
.then(response => response.json())
.then(data => console.log('创建的用户:', data));
// 使用async/await
async function fetchUserData(userId) {
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP错误! 状态: ${response.status}`);
}
const user = await response.json();
return user;
} catch (error) {
console.error('获取用户数据失败:', error);
throw error;
}
}
// 上传文件
async function uploadFile(file) {
const formData = new FormData();
formData.append('file', file);
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
});
return response.json();
}
Fetch API高级用法
高级Fetch用法
// 请求超时处理
function fetchWithTimeout(url, options = {}, timeout = 5000) {
return Promise.race([
fetch(url, options),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('请求超时')), timeout)
)
]);
}
// 重试机制
async function fetchWithRetry(url, options = {}, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url, options);
if (response.ok) return response;
throw new Error(`HTTP ${response.status}`);
} catch (error) {
if (i === retries - 1) throw error;
console.log(`请求失败,${retries - i - 1}次重试机会`);
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
}
}
}
// 请求取消
const controller = new AbortController();
const signal = controller.signal;
fetch('/api/data', { signal })
.then(response => response.json())
.then(data => console.log(data))
.catch(err => {
if (err.name === 'AbortError') {
console.log('请求被取消');
}
});
// 取消请求
// controller.abort();
Storage API
Storage API提供了在浏览器中存储数据的机制,包括localStorage和sessionStorage。
存储类型比较
| 存储类型 | 持久性 | 作用域 | 容量 | 适用场景 |
|---|---|---|---|---|
| localStorage | 永久存储 | 同源窗口共享 | 5-10MB | 用户偏好设置、缓存数据 |
| sessionStorage | 会话期间 | 单个标签页 | 5-10MB | 表单数据、临时状态 |
| Cookies | 可设置过期时间 | 同源窗口共享 | 4KB | 身份验证、会话管理 |
| IndexedDB | 永久存储 | 同源窗口共享 | 大量数据 | 复杂数据结构、离线应用 |
Storage API使用示例
// localStorage - 持久化存储
localStorage.setItem('username', '张三');
localStorage.setItem('theme', 'dark');
// 获取数据
const username = localStorage.getItem('username');
const theme = localStorage.getItem('theme') || 'light';
// 移除数据
localStorage.removeItem('username');
// 清空所有数据
// localStorage.clear();
// 存储对象
const user = { name: '李四', age: 25, preferences: { theme: 'dark' } };
localStorage.setItem('user', JSON.stringify(user));
// 读取对象
const storedUser = JSON.parse(localStorage.getItem('user') || '{}');
// sessionStorage - 会话存储(标签页关闭后清除)
sessionStorage.setItem('sessionId', 'abc123');
const sessionId = sessionStorage.getItem('sessionId');
// Storage事件监听(在其他标签页修改storage时触发)
window.addEventListener('storage', (event) => {
console.log('Storage发生变化:', {
key: event.key,
oldValue: event.oldValue,
newValue: event.newValue,
url: event.url
});
});
// 封装Storage工具类
class StorageManager {
static set(key, value) {
try {
const serializedValue = JSON.stringify(value);
localStorage.setItem(key, serializedValue);
} catch (error) {
console.error('存储数据失败:', error);
}
}
static get(key, defaultValue = null) {
try {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : defaultValue;
} catch (error) {
console.error('读取数据失败:', error);
return defaultValue;
}
}
static remove(key) {
localStorage.removeItem(key);
}
static clear() {
localStorage.clear();
}
}
// 使用工具类
StorageManager.set('userSettings', { theme: 'dark', language: 'zh-CN' });
const settings = StorageManager.get('userSettings', {});
Geolocation API
Geolocation API允许Web应用访问用户的地理位置信息。
地理位置API使用示例
// 检查浏览器支持
if (!navigator.geolocation) {
console.error('此浏览器不支持地理位置API');
} else {
console.log('地理位置API可用');
}
// 获取当前位置
navigator.geolocation.getCurrentPosition(
// 成功回调
(position) => {
const { latitude, longitude, accuracy } = position.coords;
console.log('位置获取成功:');
console.log(`纬度: ${latitude}`);
console.log(`经度: ${longitude}`);
console.log(`精度: ${accuracy}米`);
// 使用位置信息
updateLocationDisplay(latitude, longitude);
},
// 错误回调
(error) => {
console.error('获取位置失败:', error.message);
switch(error.code) {
case error.PERMISSION_DENIED:
alert('用户拒绝了位置访问请求');
break;
case error.POSITION_UNAVAILABLE:
alert('位置信息不可用');
break;
case error.TIMEOUT:
alert('获取位置超时');
break;
default:
alert('发生未知错误');
}
},
// 选项
{
enableHighAccuracy: true, // 高精度模式
timeout: 10000, // 超时时间(毫秒)
maximumAge: 60000 // 缓存位置的最大年龄
}
);
// 持续监听位置变化
let watchId = null;
function startWatchingPosition() {
watchId = navigator.geolocation.watchPosition(
(position) => {
const { latitude, longitude } = position.coords;
updateMapPosition(latitude, longitude);
},
(error) => {
console.error('位置监听错误:', error);
},
{
enableHighAccuracy: false,
timeout: 5000,
maximumAge: 30000
}
);
}
function stopWatchingPosition() {
if (watchId !== null) {
navigator.geolocation.clearWatch(watchId);
watchId = null;
}
}
// 计算两个位置之间的距离(Haversine公式)
function calculateDistance(lat1, lon1, lat2, lon2) {
const R = 6371; // 地球半径(公里)
const dLat = (lat2 - lat1) * Math.PI / 180;
const dLon = (lon2 - lon1) * Math.PI / 180;
const a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon/2) * Math.sin(dLon/2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
const distance = R * c;
return distance; // 返回公里数
}
Canvas API
Canvas API提供了通过JavaScript绘制图形的能力。
Canvas绘图示例
// 获取Canvas元素和上下文
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// 设置Canvas尺寸
canvas.width = 800;
canvas.height = 600;
// 绘制矩形
ctx.fillStyle = 'blue';
ctx.fillRect(50, 50, 100, 100);
ctx.strokeStyle = 'red';
ctx.lineWidth = 2;
ctx.strokeRect(200, 50, 100, 100);
// 绘制圆形
ctx.beginPath();
ctx.arc(400, 100, 50, 0, Math.PI * 2);
ctx.fillStyle = 'green';
ctx.fill();
ctx.stroke();
// 绘制文本
ctx.font = '24px Arial';
ctx.fillStyle = 'black';
ctx.textAlign = 'center';
ctx.fillText('Hello Canvas', 400, 200);
// 绘制路径
ctx.beginPath();
ctx.moveTo(50, 300);
ctx.lineTo(150, 250);
ctx.lineTo(250, 350);
ctx.closePath();
ctx.fillStyle = 'orange';
ctx.fill();
ctx.strokeStyle = 'purple';
ctx.stroke();
// 绘制图像
const image = new Image();
image.onload = function() {
ctx.drawImage(image, 300, 250, 100, 100);
};
image.src = 'path/to/image.jpg';
// 渐变
const gradient = ctx.createLinearGradient(500, 250, 600, 350);
gradient.addColorStop(0, 'red');
gradient.addColorStop(0.5, 'yellow');
gradient.addColorStop(1, 'green');
ctx.fillStyle = gradient;
ctx.fillRect(500, 250, 100, 100);
// 动画示例
let x = 0;
function animate() {
// 清除画布
ctx.clearRect(0, 400, canvas.width, 200);
// 绘制移动的圆形
ctx.beginPath();
ctx.arc(x, 500, 30, 0, Math.PI * 2);
ctx.fillStyle = 'red';
ctx.fill();
// 更新位置
x += 2;
if (x > canvas.width + 30) {
x = -30;
}
// 继续动画
requestAnimationFrame(animate);
}
// 开始动画
animate();
其他重要Web APIs
| API名称 | 用途 | 兼容性 |
|---|---|---|
| Intersection Observer API | 监听元素是否进入视口 | 现代浏览器 |
| Web Workers API | 在后台线程运行脚本 | 现代浏览器 |
| Service Worker API | 控制网络请求和缓存 | 现代浏览器 |
| WebSocket API | 全双工通信 | 现代浏览器 |
| WebRTC API | 实时音视频通信 | 现代浏览器 |
| IndexedDB API | 客户端数据库 | 现代浏览器 |
| Notification API | 系统通知 | 现代浏览器 |
| Clipboard API | 剪贴板操作 | 现代浏览器 |
Web Workers API
Web Workers允许在后台线程中运行JavaScript代码,避免阻塞主线程。
Web Workers示例
// main.js - 主线程
const worker = new Worker('worker.js');
// 发送消息给Worker
worker.postMessage({ type: 'CALCULATE', data: [1, 2, 3, 4, 5] });
// 接收Worker的消息
worker.onmessage = function(e) {
console.log('Worker返回结果:', e.data);
};
// 处理Worker错误
worker.onerror = function(e) {
console.error('Worker错误:', e);
};
// worker.js - Worker线程
self.onmessage = function(e) {
if (e.data.type === 'CALCULATE') {
const result = e.data.data.reduce((sum, num) => sum + num, 0);
self.postMessage(result);
}
};
Service Worker API
Service Worker是浏览器在后台运行的脚本,可以拦截和处理网络请求,实现离线缓存等功能。
Service Worker示例
// 注册Service Worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('Service Worker注册成功:', registration);
})
.catch(error => {
console.log('Service Worker注册失败:', error);
});
}
// sw.js - Service Worker文件
self.addEventListener('install', event => {
console.log('Service Worker安装中...');
event.waitUntil(
caches.open('v1').then(cache => {
return cache.addAll([
'/',
'/index.html',
'/styles/main.css',
'/scripts/main.js'
]);
})
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request);
})
);
});
实践练习
Web APIs 交互演示
Storage API 演示
演示 localStorage 和 sessionStorage 的使用
Storage API 演示输出将显示在这里...
Canvas API 演示
演示 Canvas 2D 绘图功能
Canvas API 演示输出将显示在这里...
Fetch API 演示
演示网络请求和数据获取
Fetch API 演示输出将显示在这里...
Geolocation API 演示
演示地理位置获取功能
Geolocation API 演示输出将显示在这里...
Web Workers 演示
演示后台线程计算
Web Workers 演示输出将显示在这里...
下一步学习
掌握了Web APIs后,可以继续学习:
- JavaScript参考手册 - 查阅完整的JavaScript API参考
- 模块化 - 深入学习代码组织和架构
- 设计模式 - 学习常用的JavaScript设计模式