1. HTML基础概念解析
HTML(HyperText Markup Language)作为构建万维网的基石语言,本质上是一种用于描述网页结构和内容的标记语言。不同于编程语言,HTML通过特定的标签系统来定义文档中的各个元素及其相互关系。
1.1 HTML的核心特性
HTML文档由一系列嵌套的标签组成,这些标签指示浏览器如何显示内容。典型的HTML文档结构包含以下基本元素:
html复制<!DOCTYPE html>
<html>
<head>
<title>页面标题</title>
</head>
<body>
<h1>这是一个标题</h1>
<p>这是一个段落。</p>
</body>
</html>
关键特性包括:
- 标签系统:由尖括号包围的关键词(如
<p>) - 元素嵌套:标签可以包含其他标签形成层次结构
- 属性配置:通过属性为元素添加额外信息(如
<img src="image.jpg">)
1.2 现代HTML的发展
HTML5作为当前标准,引入了许多新特性:
- 语义化标签(
<article>,<section>等) - 多媒体支持(
<video>,<audio>) - 图形绘制(
<canvas>) - 本地存储API
- 设备访问能力
2. HTML核心元素详解
2.1 文档结构元素
html复制<!DOCTYPE html> <!-- 文档类型声明 -->
<html lang="zh-CN"> <!-- 根元素 -->
<head> <!-- 元信息容器 -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文档标题</title>
</head>
<body> <!-- 可见内容区域 -->
<!-- 页面内容 -->
</body>
</html>
2.2 常用内容元素
文本元素
html复制<h1>至<h6> <!-- 标题 -->
<p>段落文本</p>
<span>行内文本容器</span>
<strong>强调文本</strong>
<em>斜体强调</em>
媒体元素
html复制<img src="image.jpg" alt="描述文本">
<video controls>
<source src="movie.mp4" type="video/mp4">
</video>
<audio controls>
<source src="audio.mp3" type="audio/mpeg">
</audio>
表单元素
html复制<form action="/submit" method="post">
<input type="text" name="username" placeholder="用户名">
<input type="password" name="pwd">
<input type="submit" value="提交">
</form>
3. HTML5新特性实践
3.1 语义化布局
html复制<header>网站页眉</header>
<nav>导航栏</nav>
<main>
<article>
<section>内容区块1</section>
<section>内容区块2</section>
</article>
<aside>侧边栏</aside>
</main>
<footer>网站页脚</footer>
3.2 Canvas绘图
html复制<canvas id="myCanvas" width="200" height="100"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(10, 10, 150, 80);
</script>
3.3 Web存储
javascript复制// 本地存储
localStorage.setItem('username', 'John');
console.log(localStorage.getItem('username'));
// 会话存储
sessionStorage.setItem('token', 'abc123');
4. HTML开发最佳实践
4.1 可访问性优化
html复制<!-- 添加alt属性 -->
<img src="logo.png" alt="公司标志">
<!-- 使用ARIA属性 -->
<button aria-label="关闭">X</button>
<!-- 正确的标签使用 -->
<label for="email">邮箱:</label>
<input type="email" id="email">
4.2 性能优化技巧
html复制<!-- 延迟加载图片 -->
<img src="image.jpg" loading="lazy">
<!-- 预加载关键资源 -->
<link rel="preload" href="style.css" as="style">
<!-- 使用picture元素响应式图片 -->
<picture>
<source media="(min-width: 800px)" srcset="large.jpg">
<source media="(min-width: 400px)" srcset="medium.jpg">
<img src="small.jpg" alt="响应式图片">
</picture>
4.3 表单验证增强
html复制<input type="email" required placeholder="请输入邮箱">
<input type="number" min="1" max="100" step="1">
<input type="text" pattern="[A-Za-z]{3}">
5. 常见问题与解决方案
5.1 跨浏览器兼容性
问题:不同浏览器对HTML特性的支持程度不同
解决方案:
- 使用特性检测(Modernizr)
- 添加polyfill
- 参考caniuse.com检查兼容性
5.2 移动端适配
关键点:
html复制<meta name="viewport" content="width=device-width, initial-scale=1">
- 使用相对单位(rem, %)
- 避免固定宽度
- 测试不同设备尺寸
5.3 SEO优化基础
html复制<!-- 基础SEO标签 -->
<title>页面标题 - 网站名称</title>
<meta name="description" content="页面描述">
<meta name="keywords" content="关键词1,关键词2">
<!-- 结构化数据 -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "文章标题"
}
</script>
6. HTML开发工具链
6.1 编辑器推荐
- VS Code(HTML插件:Auto Close Tag, HTML CSS Support)
- Sublime Text
- WebStorm
6.2 验证工具
- W3C验证器(validator.w3.org)
- Lighthouse(Chrome DevTools)
- HTMLHint(代码静态分析)
6.3 调试技巧
javascript复制// 检查元素属性
console.dir(document.getElementById('element'));
// 监听DOM变化
const observer = new MutationObserver(callback);
observer.observe(targetNode, config);
7. HTML与其他技术配合
7.1 与CSS集成
html复制<!-- 内联样式 -->
<div style="color: red;"></div>
<!-- 内部样式表 -->
<style>
body { font-family: Arial; }
</style>
<!-- 外部样式表 -->
<link rel="stylesheet" href="styles.css">
7.2 与JavaScript交互
html复制<!-- 内联脚本 -->
<button onclick="alert('Clicked')">点击</button>
<!-- 内部脚本 -->
<script>
document.querySelector('button').addEventListener('click', () => {
console.log('按钮被点击');
});
</script>
<!-- 外部脚本 -->
<script src="app.js" defer></script>
8. HTML未来发展
8.1 Web Components
html复制<!-- 自定义元素 -->
<my-component></my-component>
<script>
class MyComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
this.shadowRoot.innerHTML = `<p>自定义组件内容</p>`;
}
}
customElements.define('my-component', MyComponent);
</script>
8.2 渐进式Web应用(PWA)
html复制<!-- 清单文件 -->
<link rel="manifest" href="/manifest.json">
<!-- 服务工作者注册 -->
<script>
if('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
</script>
9. 实际项目中的HTML实践
9.1 响应式邮件模板
html复制<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>邮件标题</title>
<style type="text/css">
/* 内联样式确保邮件客户端兼容 */
body { margin: 0; padding: 0; }
.container { width: 100%; max-width: 600px; }
</style>
</head>
<body>
<table class="container" cellpadding="0" cellspacing="0">
<tr>
<td>
<!-- 邮件内容 -->
</td>
</tr>
</table>
</body>
</html>
9.2 单页应用(SPA)基础结构
html复制<!DOCTYPE html>
<html>
<head>
<title>单页应用</title>
<link rel="stylesheet" href="app.css">
</head>
<body>
<div id="app">
<!-- 动态内容将在这里渲染 -->
</div>
<script src="router.js"></script>
<script src="app.js"></script>
</body>
</html>
10. HTML性能优化进阶
10.1 关键渲染路径优化
html复制<!-- 关键CSS内联 -->
<style>
/* 首屏关键样式 */
</style>
<!-- 非关键CSS异步加载 -->
<link rel="preload" href="non-critical.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="non-critical.css"></noscript>
10.2 资源加载策略
html复制<!-- 预连接 -->
<link rel="preconnect" href="https://cdn.example.com">
<!-- DNS预取 -->
<link rel="dns-prefetch" href="//cdn.example.com">
<!-- 预加载关键资源 -->
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
10.3 现代图片技术
html复制<!-- WebP格式优先 -->
<picture>
<source type="image/webp" srcset="image.webp">
<img src="image.jpg" alt="示例图片">
</picture>
<!-- SVG矢量图形 -->
<img src="logo.svg" alt="公司标志" width="200" height="100">
<!-- 响应式图片 -->
<img srcset="small.jpg 480w, medium.jpg 768w, large.jpg 1200w"
sizes="(max-width: 600px) 480px, (max-width: 1200px) 768px, 1200px"
src="fallback.jpg" alt="响应式图片">
11. HTML安全实践
11.1 防止XSS攻击
html复制<!-- 避免内联事件处理 -->
<!-- 不推荐 -->
<button onclick="doSomething()">点击</button>
<!-- 推荐 -->
<button id="safe-btn">点击</button>
<script>
document.getElementById('safe-btn').addEventListener('click', doSomething);
</script>
11.2 内容安全策略(CSP)
html复制<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self' https://trusted.cdn.com">
11.3 表单安全
html复制<form action="/process" method="post">
<!-- CSRF令牌 -->
<input type="hidden" name="_csrf" value="token-value">
<!-- 自动完成控制 -->
<input type="password" autocomplete="current-password">
</form>
12. HTML调试与测试
12.1 浏览器开发者工具
- 元素检查器(Ctrl+Shift+C)
- DOM断点
- 网络请求分析
- 性能分析工具
12.2 自动化测试
html复制<!-- 测试ID属性 -->
<button data-testid="submit-btn">提交</button>
javascript复制// 测试示例(使用Jest+Testing Library)
test('提交按钮存在', () => {
render(<MyComponent />);
expect(screen.getByTestId('submit-btn')).toBeInTheDocument();
});
12.3 跨设备测试
- 浏览器响应式设计模式
- BrowserStack等云测试平台
- 真实设备测试矩阵
13. HTML与Web标准演进
13.1 新提案关注
- Popover API
- View Transitions
- Container Queries
- Scoped CSS
13.2 标准跟踪资源
- W3C规范文档
- WHATWG HTML Living Standard
- GitHub上的草案仓库
- 浏览器厂商博客
14. HTML学习资源推荐
14.1 官方文档
- MDN Web Docs(developer.mozilla.org)
- HTML规范(html.spec.whatwg.org)
- W3C标准(w3.org/TR/html52)
14.2 在线课程
- freeCodeCamp HTML教程
- Codecademy HTML课程
- Udemy现代HTML5教程
14.3 实践平台
- CodePen
- JSFiddle
- Glitch
15. HTML项目架构建议
15.1 文件组织
code复制project/
├── index.html
├── assets/
│ ├── css/
│ ├── js/
│ └── images/
├── partials/ # 可复用HTML片段
└── views/ # 多页面应用的各个页面
15.2 模板引擎集成
html复制<!-- Handlebars示例 -->
{{#each items}}
<div class="item">
<h3>{{title}}</h3>
<p>{{description}}</p>
</div>
{{/each}}
15.3 静态站点生成
html复制<!-- Eleventy示例 -->
---
title: 我的页面
---
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
{% include "header.html" %}
<main>{{ content }}</main>
</body>
</html>
16. HTML与无障碍设计
16.1 ARIA角色
html复制<div role="navigation" aria-label="主导航">
<!-- 导航内容 -->
</div>
<button aria-expanded="false" aria-controls="dropdown1">
菜单
</button>
<ul id="dropdown1" aria-hidden="true">
<li><a href="#">选项1</a></li>
</ul>
16.2 键盘导航
html复制<!-- 可聚焦元素 -->
<div tabindex="0">可通过键盘聚焦的元素</div>
<!-- 跳过导航链接 -->
<a href="#maincontent" class="skip-link">跳至主内容</a>
<main id="maincontent">
<!-- 页面主要内容 -->
</main>
16.3 无障碍测试工具
- axe DevTools
- WAVE评估工具
- VoiceOver屏幕阅读器
- 键盘导航测试
17. HTML国际化
17.1 多语言支持
html复制<html lang="zh-CN">
<head>
<meta charset="UTF-8">
</head>
<body>
<p dir="auto">文本方向自动检测</p>
</body>
</html>
17.2 日期与数字格式
html复制<time datetime="2023-12-25">2023年圣诞节</time>
<span data-number="1000000">1,000,000</span>
<script>
document.querySelector('[data-number]').textContent =
new Intl.NumberFormat(navigator.language).format(
parseFloat(document.querySelector('[data-number]').dataset.number)
);
</script>
18. HTML与Web组件化
18.1 自定义元素
javascript复制class MyCounter extends HTMLElement {
constructor() {
super();
this.count = 0;
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<button id="dec">-</button>
<span id="count">0</span>
<button id="inc">+</button>
`;
}
connectedCallback() {
this.shadowRoot.getElementById('inc').addEventListener('click', () => this.increment());
this.shadowRoot.getElementById('dec').addEventListener('click', () => this.decrement());
}
increment() {
this.count++;
this.update();
}
decrement() {
this.count--;
this.update();
}
update() {
this.shadowRoot.getElementById('count').textContent = this.count;
}
}
customElements.define('my-counter', MyCounter);
html复制<my-counter></my-counter>
18.2 Shadow DOM封装
javascript复制class FancyButton extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({mode: 'open'});
shadow.innerHTML = `
<style>
button {
background: linear-gradient(to right, #ff8a00, #da1b60);
border: none;
color: white;
padding: 10px 20px;
border-radius: 20px;
cursor: pointer;
font-size: 16px;
}
</style>
<button><slot></slot></button>
`;
}
}
customElements.define('fancy-button', FancyButton);
html复制<fancy-button>点击我</fancy-button>
19. HTML与服务器端渲染
19.1 基本SSR概念
html复制<!-- 服务端生成的动态内容 -->
<div id="app">
<!-- 服务端渲染的初始内容 -->
<div class="product" data-id="123">
<h2>产品名称</h2>
<p>产品描述...</p>
</div>
</div>
<!-- 客户端hydrate脚本 -->
<script src="client.js" async defer></script>
19.2 混合渲染策略
html复制<!-- 静态生成部分 -->
<header>
<!-- 静态导航 -->
</header>
<!-- 动态内容占位 -->
<div id="dynamic-content">
<!-- 服务端渲染的初始内容 -->
{{#each products}}
<div class="product">{{name}}</div>
{{/each}}
</div>
<!-- 客户端JS接管 -->
<script>
// 后续动态内容加载
fetch('/more-products')
.then(res => res.json())
.then(products => {
document.getElementById('dynamic-content').innerHTML +=
products.map(p => `<div class="product">${p.name}</div>`).join('');
});
</script>
20. HTML未来展望
20.1 新兴提案
-
Declarative Shadow DOM:
html复制<host-element> <template shadowroot="open"> <style>:host { display: block; }</style> <slot></slot> </template> <h2>Light DOM内容</h2> </host-element> -
HTML Modules:
html复制<script type="module" src="components/my-component.html"></script>
20.2 Web与原生融合
html复制<!-- 文件系统访问 -->
<input type="file" id="file-input" webkitdirectory>
<!-- 设备能力 -->
<button id="camera-btn">打开摄像头</button>
<video id="camera-view" autoplay></video>
<script>
document.getElementById('camera-btn').addEventListener('click', async () => {
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
document.getElementById('camera-view').srcObject = stream;
});
</script>
21. HTML性能基准测试
21.1 关键指标测量
html复制<!-- 性能标记 -->
<script>
performance.mark('html-start');
</script>
<!-- 页面内容 -->
<script>
performance.mark('html-end');
performance.measure('html-render', 'html-start', 'html-end');
console.log(performance.getEntriesByName('html-render')[0].duration);
</script>
21.2 优化前后对比
| 优化措施 | DOMContentLoaded时间 | 完全加载时间 |
|---|---|---|
| 原始版本 | 1200ms | 2500ms |
| 延迟加载图片 | 800ms | 1800ms |
| 关键CSS内联 | 600ms | 1500ms |
| 资源预加载 | 550ms | 1200ms |
22. HTML与WebAssembly集成
22.1 基本集成模式
html复制<script>
// 加载Wasm模块
WebAssembly.instantiateStreaming(fetch('module.wasm'))
.then(obj => {
// 调用Wasm导出的函数
const result = obj.instance.exports.add(1, 2);
console.log(result);
});
</script>
22.2 Wasm组件示例
html复制<canvas id="wasm-canvas"></canvas>
<script>
const canvas = document.getElementById('wasm-canvas');
const ctx = canvas.getContext('2d');
(async () => {
const { instance } = await WebAssembly.instantiateStreaming(
fetch('graphics.wasm'),
{
env: {
render: (ptr, width, height) => {
const imageData = new ImageData(
new Uint8ClampedArray(
instance.exports.memory.buffer, ptr, width*height*4),
width, height);
ctx.putImageData(imageData, 0, 0);
}
}
}
);
instance.exports.init();
instance.exports.render_frame();
})();
</script>
23. HTML与Web Workers
23.1 基本用法
html复制<script>
// 主线程
const worker = new Worker('worker.js');
worker.postMessage('开始计算');
worker.onmessage = (e) => {
console.log('收到结果:', e.data);
};
</script>
javascript复制// worker.js
self.onmessage = (e) => {
console.log('收到消息:', e.data);
// 执行耗时计算
const result = heavyCalculation();
self.postMessage(result);
};
23.2 共享Worker
html复制<script>
// 多个页面共享的Worker
const sharedWorker = new SharedWorker('shared-worker.js');
sharedWorker.port.postMessage('共享消息');
sharedWorker.port.onmessage = (e) => {
console.log('共享结果:', e.data);
};
</script>
24. HTML与WebSocket实时通信
24.1 基本实现
html复制<div id="messages"></div>
<input type="text" id="message-input">
<button id="send-btn">发送</button>
<script>
const socket = new WebSocket('wss://example.com/ws');
const messages = document.getElementById('messages');
const input = document.getElementById('message-input');
socket.onmessage = (e) => {
messages.innerHTML += `<div>${e.data}</div>`;
};
document.getElementById('send-btn').addEventListener('click', () => {
socket.send(input.value);
input.value = '';
});
</script>
24.2 实时数据展示
html复制<canvas id="data-chart" width="600" height="400"></canvas>
<script>
const ctx = document.getElementById('data-chart').getContext('2d');
const chart = new Chart(ctx, { type: 'line', data: { datasets: [] } });
const ws = new WebSocket('wss://example.com/data-feed');
ws.onmessage = (e) => {
const data = JSON.parse(e.data);
chart.data.datasets.forEach(dataset => {
dataset.data.push(data.value);
});
chart.update();
};
</script>
25. HTML与WebRTC
25.1 视频通话实现
html复制<video id="local-video" autoplay muted></video>
<video id="remote-video" autoplay></video>
<button id="start-call">开始通话</button>
<script>
const localVideo = document.getElementById('local-video');
const remoteVideo = document.getElementById('remote-video');
const startButton = document.getElementById('start-call');
let localStream;
let peerConnection;
startButton.addEventListener('click', async () => {
localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
localVideo.srcObject = localStream;
// 创建RTCPeerConnection
peerConnection = new RTCPeerConnection();
peerConnection.addStream(localStream);
peerConnection.onicecandidate = (e) => {
if (e.candidate) {
// 发送ICE候选
}
};
peerConnection.onaddstream = (e) => {
remoteVideo.srcObject = e.stream;
};
// 发起offer
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);
// 发送offer到对方
});
</script>
26. HTML与WebGL集成
26.1 基础WebGL场景
html复制<canvas id="gl-canvas" width="800" height="600"></canvas>
<script>
const canvas = document.getElementById('gl-canvas');
const gl = canvas.getContext('webgl');
if (!gl) {
alert('浏览器不支持WebGL');
}
// 顶点着色器
const vsSource = `
attribute vec4 aPosition;
void main() {
gl_Position = aPosition;
}
`;
// 片段着色器
const fsSource = `
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;
// 初始化着色器程序
const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
// 创建缓冲区并绘制
const vertices = new Float32Array([
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5
]);
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
const position = gl.getAttribLocation(shaderProgram, 'aPosition');
gl.enableVertexAttribArray(position);
gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 3);
</script>
27. HTML与WebXR
27.1 VR基础实现
html复制<button id="xr-button">进入VR</button>
<script>
const xrButton = document.getElementById('xr-button');
if (navigator.xr) {
navigator.xr.isSessionSupported('immersive-vr').then((supported) => {
xrButton.textContent = supported ? '进入VR' : 'VR不可用';
xrButton.disabled = !supported;
});
} else {
xrButton.textContent = 'XR API不可用';
xrButton.disabled = true;
}
xrButton.addEventListener('click', async () => {
const session = await navigator.xr.requestSession('immersive-vr');
session.addEventListener('end', () => {
xrButton.textContent = '进入VR';
});
// 设置XR渲染循环
const gl = canvas.getContext('webgl', { xrCompatible: true });
const xrRefSpace = await session.requestReferenceSpace('local');
function onXRFrame(time, frame) {
const pose = frame.getViewerPose(xrRefSpace);
if (pose) {
// 渲染场景
}
session.requestAnimationFrame(onXRFrame);
}
session.requestAnimationFrame(onXRFrame);
});
</script>
28. HTML与机器学习
28.1 TensorFlow.js集成
html复制<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest"></script>
<video id="webcam" autoplay></video>
<canvas id="output"></canvas>
<script>
const webcam = document.getElementById('webcam');
const output = document.getElementById('output');
const ctx = output.getContext('2d');
// 加载模型
async function loadModel() {
const model = await tf.loadLayersModel('model.json');
return model;
}
// 访问摄像头
async function setupWebcam() {
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
webcam.srcObject = stream;
return new Promise((resolve) => {
webcam.onloadedmetadata = () => resolve();
});
}
// 实时预测
async function runPrediction() {
const model = await loadModel();
await setupWebcam();
function predict() {
// 从视频捕获帧并预处理
const tensor = tf.browser.fromPixels(webcam)
.resizeNearestNeighbor([224, 224])
.toFloat()
.expandDims();
// 执行预测
const predictions = model.predict(tensor);
const results = predictions.dataSync();
// 显示结果
ctx.drawImage(webcam, 0, 0);
ctx.fillText(`预测结果: ${results[0]}`, 10, 20);
requestAnimationFrame(predict);
}
predict();
}
runPrediction();
</script>
29. HTML与区块链交互
29.1 Web3集成
html复制<button id="connect-wallet">连接钱包</button>
<div id="wallet-address"></div>
<script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
<script>
const connectButton = document.getElementById('connect-wallet');
const walletAddress = document.getElementById('wallet-address');
connectButton.addEventListener('click', async () => {
if (window.ethereum) {
try {
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
walletAddress.textContent = `已连接: ${accounts[0]}`;
// 初始化Web3
const web3 = new Web3(window.ethereum);
// 获取余额
const balance = await web3.eth.getBalance(accounts[0]);
console.log('余额:', web3.utils.fromWei(balance, 'ether'), 'ETH');
} catch (error) {
console.error('用户拒绝连接:', error);
}
} else {
alert('请安装MetaMask或其他Web3钱包');
}
});
</script>
30. HTML与物联网(IoT)
30.1 MQTT实时数据展示
html复制<div id="sensor-data">
<p>温度: <span id="temperature">--</span>°C</p>
<p>湿度: <span id="humidity">--</span>%</p>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.1.0/paho-mqtt.min.js"></script>
<script>
const client = new Paho.MQTT.Client("mqtt.example.com", 8083, "clientId");
client.onConnectionLost = (response) => {
console.log("连接断开:", response.errorMessage);
};
client.onMessageArrived = (message) => {
const data = JSON.parse(message.payloadString);
document.getElementById('temperature').textContent = data.temp;
document.getElementById('humidity').textContent = data.humidity;
};
client.connect({
onSuccess: () => {
console.log("MQTT连接成功");
client.subscribe("sensors/room1");
},
onFailure: (err) => {
console.error("连接失败:", err.errorMessage);
}
});
</script>
