mindmap
root((动态扩展))
DOM Manipulation
Element Selection
Event Handling
State Management
UI Updates
Local Storage
Data Persistence
Key-Value Pairs
Session Management
User Preferences
API Integration
HTTP Requests
Authentication
Data Parsing
Error Handling
Async Programming
Promises
Async/Await
Error Catching
Non-blocking Code
User Experience
Loading States
Error Messages
Smooth Transitions
Data Validation
✅ 按照对应文件中的编号段落知道在哪里放置你的代码
设置扩展中要操作的元素
在你的 JavaScript 操作界面之前,需要先获取特定的 HTML 元素引用。就像望远镜需要对准特定的星星一样——伽利略研究木星的卫星前必须先定位并聚焦于木星。
flowchart LR
A[JavaScript 代码] --> B[document.querySelector]
B --> C[CSS 选择器]
C --> D[HTML 元素]
D --> E[".form-data"]
D --> F[".region-name"]
D --> G[".api-key"]
D --> H[".loading"]
D --> I[".errors"]
D --> J[".result-container"]
E --> K[表单元素]
F --> L[输入字段]
G --> M[输入字段]
H --> N[UI 元素]
I --> O[UI 元素]
J --> P[UI 元素]
style A fill:#e1f5fe
style D fill:#e8f5e8
style K fill:#fff3e0
style L fill:#fff3e0
style M fill:#fff3e0
现在我们将扩展连接到外部数据源,通过 API 获取数据。这使你的扩展从独立工具变成可以访问互联网上实时信息的应用。
理解 API
API 是不同应用间通信的方式。可以把它想象成 19 世纪连接远距离城市的电报系统——操作员会向远方电报站发送请求,并收取返回的信息。每次你查看社交媒体、问语音助手问题、或用送货应用时,都离不开 API 帮助完成数据交换。
flowchart TD
A[您的扩展] --> B[HTTP 请求]
B --> C[CO2 信号 API]
C --> D{请求有效吗?}
D -->|是| E[查询数据库]
D -->|否| F[返回错误]
E --> G[碳排放数据]
G --> H[JSON 响应]
H --> I[您的扩展]
F --> I
I --> J[更新界面]
subgraph "API 请求"
K[请求头: auth-token]
L[参数: countryCode]
M[方法: GET]
end
subgraph "API 响应"
N[碳强度]
O[化石燃料百分比]
P[时间戳]
end
style C fill:#e8f5e8
style G fill:#fff3e0
style I fill:#e1f5fe
sequenceDiagram
participant Ext as 扩展
participant API as CO2 信号 API
participant DB as 数据库
Ext->>API: 使用认证令牌请求
API->>API: 验证令牌
API->>DB: 查询碳数据
DB->>API: 返回数据
API->>Ext: JSON 响应
Ext->>Ext: 更新界面
创建获取并展示碳使用数据的函数:
// 现代的 fetch API 方法(不需要外部依赖)
async function displayCarbonUsage(apiKey, region) {
try {
// 从 CO2 Signal API 获取碳强度数据
const response = await fetch('https://api.co2signal.com/v1/latest', {
method: 'GET',
headers: {
'auth-token': apiKey,
'Content-Type': 'application/json'
},
// 添加特定区域的查询参数
...new URLSearchParams({ countryCode: region }) && {
url: `https://api.co2signal.com/v1/latest?countryCode=${region}`
}
});
// 检查 API 请求是否成功
if (!response.ok) {
throw new Error(`API request failed: ${response.status}`);
}
const data = await response.json();
const carbonData = data.data;
// 计算四舍五入的碳强度值
const carbonIntensity = Math.round(carbonData.carbonIntensity);
// 使用获取到的数据更新用户界面
loading.style.display = 'none';
form.style.display = 'none';
myregion.textContent = region.toUpperCase();
usage.textContent = `${carbonIntensity} grams (grams CO₂ emitted per kilowatt hour)`;
fossilfuel.textContent = `${carbonData.fossilFuelPercentage.toFixed(2)}% (percentage of fossil fuels used to generate electricity)`;
results.style.display = 'block';
// 待办:calculateColor(carbonIntensity) - 在下一节课中实现
} catch (error) {
console.error('Error fetching carbon data:', error);
// 显示用户友好的错误信息
loading.style.display = 'none';
results.style.display = 'none';
errors.textContent = 'Sorry, we couldn\'t fetch data for that region. Please check your API key and region code.';
}
}
flowchart TD
A[开始 API 调用] --> B[获取请求]
B --> C{网络成功?}
C -->|否| D[网络错误]
C -->|是| E{响应正常?}
E -->|否| F[API 错误]
E -->|是| G[解析 JSON]
G --> H{数据有效?}
H -->|否| I[数据错误]
H -->|是| J[更新界面]
D --> K[显示错误信息]
F --> K
I --> K
J --> L[隐藏加载]
K --> L
style A fill:#e1f5fe
style J fill:#e8f5e8
style K fill:#ffebee
style L fill:#f3e5f5
? 教学检查点
完整系统理解:确认你掌握整个流程:
✅ DOM 引用为什么能让 JavaScript 控控界面
✅ 本地存储如何实现跨浏览器会话的数据持久化
✅ async/await 如何让 API 调用不冻结扩展
✅ API 请求失败时会怎样,以及如何处理异常
✅ 用户体验为何包含加载状态和错误提示
? 你已经完成了:
一个浏览器扩展,它:
连接 互联网,获取真实环保数据
持久保存 用户设置跨会话
优雅处理 错误,避免崩溃
提供 流畅且专业的用户体验
通过运行 npm run build 并刷新浏览器扩展测试你的成果。你现在拥有一个功能齐全的碳足迹追踪器。下一课将添加动态图标功能,完善此扩展。
GitHub Copilot Agent 挑战 ?
使用 Agent 模式完成以下挑战:
描述: 通过添加错误处理改进和用户体验功能来增强浏览器扩展。本挑战将帮助你练习使用现代 JavaScript 模式进行 API 调用、本地存储和 DOM 操作。
提示: 创建一个增强版的 displayCarbonUsage 函数,包含:1) 失败 API 调用的指数退避重试机制,2) 调用 API 前对区域代码的输入验证,3) 带有进度指示器的加载动画,4) 在 localStorage 中缓存 API 响应及过期时间戳(缓存时长30分钟),及 5) 显示先前 API 调用历史数据的功能。同时为所有函数参数和返回类型添加适当的 TypeScript 风格 JSDoc 注释。