1. HTML5 语义化页面开发
应用场景:搭建企业官网 / 博客的基础结构,替代纯 div 布局,提升 SEO 和可读性。
核心知识点:header/nav/main/article/section/aside/footer 语义标签、meta 适配移动端。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<!-- 移动端适配核心:视口宽度=device-width,缩放1 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML5 语义化官网</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: "微软雅黑", sans-serif; }
header, nav, footer { padding: 15px; background: #333; color: #fff; }
nav ul { display: flex; list-style: none; gap: 20px; }
nav a { color: #fff; text-decoration: none; }
main { display: flex; padding: 20px; gap: 20px; }
article { flex: 3; }
aside { flex: 1; background: #f5f5f5; padding: 15px; }
section { margin-bottom: 20px; padding: 15px; border: 1px solid #eee; }
</style>
</head>
<body>
<!-- 头部:品牌/标题 -->
<header>
<h1>XX科技官网</h1>
</header>
<!-- 导航栏:核心导航 -->
<nav>
<ul>
<li><a href="#home">首页</a></li>
<li><a href="#product">产品</a></li>
<li><a href="#about">关于我们</a></li>
</ul>
</nav>
<!-- 主体内容:页面核心 -->
<main>
<!-- 主要内容区 -->
<article>
<section id="home">
<h2>首页介绍</h2>
<p>HTML5 语义化让页面结构更清晰,搜索引擎更易识别内容。</p>
</section>
<section id="product">
<h2>核心产品</h2>
<p>基于 HTML5 开发的跨端应用,兼容多设备。</p>
</section>
</article>
<!-- 侧边栏:辅助信息 -->
<aside>
<h3>联系方式</h3>
<p>电话:123456789</p>
<p>邮箱:test@xxx.com</p>
</aside>
</main>
<!-- 底部:版权/备案 -->
<footer>
<p>© 2026 XX科技 版权所有 | 备案号:粤ICP备XXXX号</p>
</footer>
</body>
</html>
关键解析:
main 标签代表页面唯一核心内容,一个页面仅一个;
meta:viewport 是移动端适配的基础,必须添加;
语义标签不影响样式,需配合 CSS 实现布局,核心是「结构语义化」而非「样式语义化」。
2. HTML5 新表单控件实战(简化表单开发)
应用场景:开发注册 / 登录 / 信息收集表单,利用 HTML5 原生控件减少 JS 开发量。
核心知识点:
input 新类型(date/email/number)、
required/pattern/placeholder 属性、
datalist 联想输入。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML5 新表单实战</title>
<style>
form { max-width: 500px; margin: 20px auto; padding: 20px; border: 1px solid #eee; }
.form-item { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; }
input, select { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; }
button { padding: 10px 20px; background: #007bff; color: #fff; border: none; border-radius: 4px; cursor: pointer; }
</style>
</head>
<body>
<form action="#" method="post">
<div class="form-item">
<label for="email">邮箱(原生验证):</label>
<input type="email" id="email" required placeholder="请输入邮箱">
</div>
<div class="form-item">
<label for="phone">手机号(正则验证):</label>
<input type="tel" id="phone" required pattern="^1[3-9]\d{9}$" placeholder="请输入手机号">
</div>
<div class="form-item">
<label for="age">年龄(数字限制):</label>
<input type="number" id="age" min="18" max="60" placeholder="18-60岁">
</div>
<div class="form-item">
<label for="birthday">生日:</label>
<input type="date" id="birthday">
</div>
<div class="form-item">
<label for="city">城市(联想输入):</label>
<input type="text" id="city" list="cityList" placeholder="输入或选择城市">
<datalist id="cityList">
<option value="北京"></option>
<option value="上海"></option>
<option value="广州"></option>
</datalist>
</div>
<button type="submit">提交</button>
</form>
</body>
</html>
关键解析:
required:标记必填项,提交时原生验证;
pattern:自定义正则验证(如手机号),无需手写 JS 验证;
type=email/number/date:浏览器原生适配输入样式(如日期选择器),提升用户体验。
3. HTML5 多媒体(音频 / 视频)开发
应用场景:
开发视频播放页、音频播放器,替代 Flash,原生支持多格式。
核心知识点:
video/audio 标签、controls/autoplay/muted/loop 属性、多格式兼容。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML5 多媒体实战</title>
<style>
.media-box { max-width: 800px; margin: 20px auto; }
video { width: 100%; border: 1px solid #eee; }
audio { width: 100%; margin-top: 20px; }
</style>
</head>
<body>
<div class="media-box">
<h3>视频播放(多格式兼容)</h3>
<!-- poster:视频封面;controls:原生控制栏;muted+autoplay:静音自动播放(浏览器允许) -->
<video
poster="cover.jpg"
controls
muted
preload="metadata"
>
<!-- 多格式兼容:浏览器自动选择支持的格式 -->
<source src="video.mp4" type="video/mp4">
<source src="video.webm" type="video/webm">
您的浏览器不支持 HTML5 视频播放,请升级浏览器!
</video>
<h3>音频播放</h3>
<audio controls loop>
<source src="music.mp3" type="audio/mpeg">
<source src="music.ogg" type="audio/ogg">
您的浏览器不支持 HTML5 音频播放!
</audio>
</div>
</body>
</html>
关键解析:
preload="metadata":仅预加载视频元数据(时长 / 封面),不加载完整视频,节省带宽;
autoplay 需配合 muted:多数浏览器禁止非静音自动播放;
多 source 标签:兼容不同浏览器(如 MP4 兼容主流浏览器,WebM 兼容火狐 / Chrome)。
4. localStorage 本地存储实战(数据持久化)
应用场景:开发「用户偏好设置」「草稿箱」「历史记录」,无需后端实现数据本地保存。
核心知识点:localStorage 增删改查、JSON 序列化 / 反序列化、数据过期处理。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>localStorage 实战</title>
<style>
.demo-box { max-width: 500px; margin: 20px auto; padding: 20px; border: 1px solid #eee; }
textarea { width: 100%; height: 100px; margin: 10px 0; padding: 8px; }
button { margin-right: 10px; padding: 8px 15px; cursor: pointer; }
</style>
</head>
<body>
<div class="demo-box">
<h3>本地草稿箱(关闭页面不丢失)</h3>
<textarea id="content" placeholder="输入内容,自动保存草稿..."></textarea>
<button onclick="saveDraft()">手动保存</button>
<button onclick="clearDraft()">清空草稿</button>
<p id="tip"></p>
</div>
<script>
const contentEl = document.getElementById('content');
const tipEl = document.getElementById('tip');
const STORAGE_KEY = 'article_draft';
// 页面加载时读取草稿
window.onload = function() {
const draft = localStorage.getItem(STORAGE_KEY);
if (draft) {
contentEl.value = draft;
tipEl.innerText = '已加载本地草稿';
}
};
// 实时保存(输入时自动保存)
contentEl.addEventListener('input', function() {
localStorage.setItem(STORAGE_KEY, this.value);
tipEl.innerText = '草稿已自动保存';
});
// 手动保存
function saveDraft() {
localStorage.setItem(STORAGE_KEY, contentEl.value);
tipEl.innerText = '草稿手动保存成功';
}
// 清空草稿
function clearDraft() {
localStorage.removeItem(STORAGE_KEY);
contentEl.value = '';
tipEl.innerText = '草稿已清空';
}
// 进阶:带过期时间的本地存储(示例)
function setStorageWithExpire(key, value, expireHours) {
const data = {
value: value,
expire: Date.now() + expireHours * 3600 * 1000 // 过期时间戳
};
localStorage.setItem(key, JSON.stringify(data));
}
// 读取带过期的存储
function getStorageWithExpire(key) {
const data = JSON.parse(localStorage.getItem(key));
if (!data) return null;
// 过期则删除并返回null
if (Date.now() > data.expire) {
localStorage.removeItem(key);
return null;
}
return data.value;
}
</script>
</body>
</html>
关键解析:
localStorage 仅存字符串,存储对象需用 JSON.stringify(),读取用 JSON.parse();
实时保存:监听 input 事件,输入时自动保存,提升用户体验;
过期处理:自定义封装带过期时间的存储方法,解决 localStorage 无原生过期的问题。
5. Canvas 2D 绘图实战(基础可视化)
应用场景:开发简单图表、验证码、手绘板,替代图片资源,动态生成图形。
核心知识点:Canvas 上下文、路径绘制、样式设置、鼠标交互。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas 实战 - 简易手绘板</title>
<style>
canvas { border: 1px solid #ccc; cursor: crosshair; }
.control { margin: 10px 0; }
button { padding: 8px 15px; cursor: pointer; }
</style>
</head>
<body>
<div class="control">
<button onclick="clearCanvas()">清空画布</button>
<label>画笔颜色:</label>
<input type="color" id="colorPicker" value="#000000">
</div>
<canvas id="drawCanvas" width="800" height="400"></canvas>
<script>
const canvas = document.getElementById('drawCanvas');
const ctx = canvas.getContext('2d');
const colorPicker = document.getElementById('colorPicker');
let isDrawing = false; // 是否正在绘制
// 开始绘制(鼠标按下)
canvas.addEventListener('mousedown', function(e) {
isDrawing = true;
// 获取鼠标在画布内的坐标(修正画布偏移)
const x = e.offsetX;
const y = e.offsetY;
ctx.beginPath(); // 开始新路径
ctx.moveTo(x, y); // 移动到起始点
ctx.lineWidth = 2; // 画笔宽度
ctx.strokeStyle = colorPicker.value; // 画笔颜色
ctx.lineCap = 'round'; // 线条端点圆润
});
// 绘制中(鼠标移动)
canvas.addEventListener('mousemove', function(e) {
if (!isDrawing) return;
const x = e.offsetX;
const y = e.offsetY;
ctx.lineTo(x, y); // 绘制线条到当前点
ctx.stroke(); // 描边(显示线条)
});
// 结束绘制(鼠标松开/离开)
canvas.addEventListener('mouseup', () => isDrawing = false);
canvas.addEventListener('mouseleave', () => isDrawing = false);
// 清空画布
function clearCanvas() {
// 清空整个画布(从0,0到宽高)
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
</script>
</body>
</html>
关键解析:
offsetX/offsetY:获取鼠标相对于画布的坐标(而非页面),避免画布偏移导致坐标错误;
lineCap='round':让画笔线条端点更圆润,提升手绘体验;
绘制逻辑:mousedown 开始路径 → mousemove 绘制线条 → mouseup 结束绘制。
6. HTML5 拖放(Drag & Drop)实战
应用场景:开发「拖拽排序」「文件上传」「组件拖拽布局」,原生实现无需第三方库。
核心知识点:draggable 属性、dragstart/dragover/drop 事件、数据传输 dataTransfer。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML5 拖放实战 - 拖拽排序</title>
<style>
.container { display: flex; gap: 10px; margin: 20px; }
.drag-item {
width: 100px; height: 100px;
background: #007bff; color: #fff;
display: flex; align-items: center; justify-content: center;
cursor: move; user-select: none; /* 禁止文字选中 */
}
.drop-area {
flex: 1; min-height: 300px;
border: 2px dashed #ccc; padding: 10px;
display: flex; flex-wrap: wrap; gap: 10px;
}
.drop-area.active { border-color: #007bff; }
</style>
</head>
<body>
<div class="container">
<!-- 可拖拽元素 -->
<div>
<div class="drag-item" draggable="true" data-id="1">元素1</div>
<div class="drag-item" draggable="true" data-id="2">元素2</div>
<div class="drag-item" draggable="true" data-id="3">元素3</div>
</div>
<!-- 放置区域 -->
<div class="drop-area" id="dropArea"></div>
</div>
<script>
const dragItems = document.querySelectorAll('.drag-item');
const dropArea = document.getElementById('dropArea');
// 1. 拖拽开始:设置传输数据
dragItems.forEach(item => {
item.addEventListener('dragstart', function(e) {
// 设置拖拽数据(id)
e.dataTransfer.setData('text/plain', this.dataset.id);
// 设置拖拽效果(视觉提示)
e.dataTransfer.effectAllowed = 'move';
// 高亮拖拽元素(可选)
this.style.opacity = '0.5';
});
// 拖拽结束:恢复样式
item.addEventListener('dragend', function() {
this.style.opacity = '1';
});
});
// 2. 拖拽经过:必须阻止默认行为,否则无法触发drop
dropArea.addEventListener('dragover', function(e) {
e.preventDefault();
this.classList.add('active');
e.dataTransfer.dropEffect = 'move'; // 设置放置效果
});
// 拖拽离开:移除高亮
dropArea.addEventListener('dragleave', function() {
this.classList.remove('active');
});
// 3. 放置元素:处理逻辑
dropArea.addEventListener('drop', function(e) {
e.preventDefault();
this.classList.remove('active');
// 获取拖拽的元素ID
const id = e.dataTransfer.getData('text/plain');
// 找到拖拽的元素
const dragItem = document.querySelector(`[data-id="${id}"]`);
// 克隆元素并添加到放置区域(也可直接移动)
const cloneItem = dragItem.cloneNode(true);
cloneItem.draggable = true; // 克隆后需重新设置draggable
this.appendChild(cloneItem);
});
</script>
</body>
</html>
关键解析:
dragover 必须阻止默认行为(e.preventDefault()),否则 drop 事件不会触发;
dataTransfer:用于传输拖拽数据(如元素 ID),仅支持字符串类型;
dragend:恢复拖拽元素样式,避免拖拽后样式异常。
7. Web Worker 实战(避免主线程阻塞)
应用场景:处理大数据计算、复杂逻辑(如数据解析、加密),避免页面卡顿。
核心知识点:Web Worker 线程创建、消息通信、错误处理、线程终止。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web Worker 实战 - 大数据计算</title>
<style>
.demo { max-width: 600px; margin: 20px auto; }
#result { margin: 20px 0; padding: 10px; border: 1px solid #eee; }
button { padding: 10px 20px; cursor: pointer; }
</style>
</head>
<body>
<div class="demo">
<h3>Web Worker 大数据计算(不阻塞页面)</h3>
<button onclick="startCalculation()">开始计算(1000万次循环)</button>
<button onclick="stopWorker()" disabled id="stopBtn">终止计算</button>
<div id="result">计算结果:等待计算...</div>
<!-- 测试页面是否卡顿:可拖动的滑块 -->
<input type="range" style="width: 100%; margin-top: 20px;" value="50">
</div>
<script>
let worker; // 保存Worker实例
const resultEl = document.getElementById('result');
const stopBtn = document.getElementById('stopBtn');
// 开始计算
function startCalculation() {
// 1. 创建Web Worker(单独的JS文件)
worker = new Worker('calculation-worker.js');
stopBtn.disabled = false;
resultEl.innerText = '计算中...';
// 2. 向Worker发送数据
worker.postMessage({ count: 10000000 });
// 3. 接收Worker返回的结果
worker.onmessage = function(e) {
resultEl.innerText = `计算结果:${e.data}(耗时:${e.data.cost}ms)`;
stopBtn.disabled = true;
worker.terminate(); // 计算完成后终止Worker
worker = null;
};
// 4. 监听Worker错误
worker.onerror = function(error) {
resultEl.innerText = `计算出错:${error.message}(行:${error.lineno})`;
stopBtn.disabled = true;
worker.terminate();
worker = null;
};
}
// 终止计算
function stopWorker() {
if (worker) {
worker.terminate();
worker = null;
resultEl.innerText = '计算已终止';
stopBtn.disabled = true;
}
}
</script>
</body>
</html>
新建 calculation-worker.js 文件(与 HTML 同目录):
// Worker线程代码(无法访问DOM、window,仅能通过postMessage通信)
self.onmessage = function(e) {
const start = Date.now();
const count = e.data.count;
let sum = 0;
// 模拟大数据计算(1000万次循环)
for (let i = 0; i < count; i++) {
sum += Math.sqrt(i) * Math.random();
}
const cost = Date.now() - start;
// 向主线程返回结果
self.postMessage({ sum: sum.toFixed(2), cost: cost });
};
关键解析:
Web Worker 无法访问 DOM、window、document,仅能通过 postMessage 与主线程通信;
计算完成 / 出错后需调用 terminate() 终止 Worker,避免内存泄漏;
优势:计算时页面滑块仍可拖动,证明主线程未阻塞。
8. Fetch API 实战(新一代网络请求)
应用场景:
替代 AJAX/XMLHttpRequest,开发接口请求、文件上传,支持 Promise 和异步编程。
核心知识点:
Fetch 基本用法、请求头设置、POST 请求、文件上传、响应处理、错误捕获。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fetch API 实战</title>
<style>
.demo { max-width: 600px; margin: 20px auto; }
#response { margin: 20px 0; padding: 10px; border: 1px solid #eee; white-space: pre-wrap; }
button { margin-right: 10px; padding: 8px 15px; cursor: pointer; }
</style>
</head>
<body>
<div class="demo">
<h3>Fetch API 实战</h3>
<button onclick="getApiData()">GET 请求(获取数据)</button>
<button onclick="postApiData()">POST 请求(提交数据)</button>
<button onclick="uploadFile()">上传文件</button>
<div id="response">响应结果:等待请求...</div>
<input type="file" id="fileInput" style="margin-top: 10px;">
</div>
<script>
const responseEl = document.getElementById('response');
const fileInput = document.getElementById('fileInput');
// 封装通用Fetch请求(简化代码)
async function request(url, options = {}) {
try {
// 默认配置
const defaultOptions = {
method: 'GET',
headers: {
'Content-Type': 'application/json' // 默认JSON格式
},
credentials: 'same-origin' // 携带同域Cookie
};
const config = { ...defaultOptions, ...options };
// 发送请求
const response = await fetch(url, config);
// 检查响应状态(Fetch仅在网络错误时reject,状态码非200需手动处理)
if (!response.ok) {
throw new Error(`请求失败:${response.status} ${response.statusText}`);
}
// 解析响应(根据返回格式选择json/text/blob等)
const data = await response.json();
return data;
} catch (error) {
responseEl.innerText = `请求错误:${error.message}`;
throw error; // 抛出错误供上层处理
}
}
// 1. GET请求(示例:获取公共API数据)
async function getApiData() {
responseEl.innerText = '请求中...';
try {
const data = await request('https://jsonplaceholder.typicode.com/posts/1');
responseEl.innerText = JSON.stringify(data, null, 2);
} catch (error) {
console.error('GET请求失败:', error);
}
}
// 2. POST请求(提交JSON数据)
async function postApiData() {
responseEl.innerText = '请求中...';
try {
const data = await request('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
body: JSON.stringify({
title: 'HTML5 Fetch 实战',
body: '这是POST请求测试',
userId: 1
})
});
responseEl.innerText = JSON.stringify(data, null, 2);
} catch (error) {
console.error('POST请求失败:', error);
}
}
// 3. 文件上传(FormData格式)
async function uploadFile() {
const file = fileInput.files[0];
if (!file) {
responseEl.innerText = '请先选择文件';
return;
}
responseEl.innerText = '上传中...';
try {
// 构建FormData(文件上传专用)
const formData = new FormData();
formData.append('file', file);
formData.append('name', '测试文件');
// 发送上传请求(注意:Content-Type需由浏览器自动设置为multipart/form-data)
const data = await request('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
body: formData,
headers: {} // 清空默认的Content-Type,避免冲突
});
responseEl.innerText = `上传成功:${JSON.stringify(data, null, 2)}`;
} catch (error) {
console.error('文件上传失败:', error);
}
}
</script>
</body>
</html>
关键解析:
Fetch 仅在「网络错误」时 reject,状态码 404/500 等需通过 response.ok 手动判断;
文件上传需用 FormData,且需清空 Content-Type,由浏览器自动设置(避免格式错误);
封装通用 request 函数:减少重复代码,统一处理错误和配置。
9. Service Worker 实战(离线缓存)
应用场景:开发 PWA 应用、实现页面离线访问、缓存静态资源,提升页面加载速度。
核心知识点:Service Worker 注册、安装、激活、缓存策略、拦截请求。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Service Worker 实战 - 离线缓存</title>
<style>
.demo { max-width: 600px; margin: 20px auto; text-align: center; }
#status { margin: 20px 0; padding: 10px; border: 1px solid #eee; }
</style>
</head>
<body>
<div class="demo">
<h3>Service Worker 离线缓存演示</h3>
<p>刷新页面后断网,仍可访问页面和缓存的资源</p>
<div id="status">Service Worker 状态:未注册</div>
<img src="logo.png" alt="测试图片" width="200">
</div>
<script>
const statusEl = document.getElementById('status');
// 1. 检查浏览器是否支持Service Worker
if ('serviceWorker' in navigator) {
window.addEventListener('load', async () => {
try {
// 2. 注册Service Worker(需在HTTPS/localhost环境下)
const registration = await navigator.serviceWorker.register('/sw.js');
if (registration.installing) {
statusEl.innerText = 'Service Worker 正在安装...';
} else if (registration.waiting) {
statusEl.innerText = 'Service Worker 已安装,等待激活...';
} else if (registration.active) {
statusEl.innerText = 'Service Worker 已激活,支持离线访问!';
}
} catch (error) {
statusEl.innerText = `Service Worker 注册失败:${error.message}`;
}
});
} else {
statusEl.innerText = '您的浏览器不支持 Service Worker';
}
</script>
</body>
</html>
新建 sw.js 文件(根目录):
// 缓存名称(更新缓存时修改名称)
const CACHE_NAME = 'html5-demo-v1';
// 需要缓存的资源列表
const CACHE_ASSETS = [
'/', // 首页
'/index.html', // HTML文件
'/logo.png' // 测试图片(替换为实际图片路径)
];
// 1. 安装阶段:缓存静态资源
self.addEventListener('install', function(e) {
// 等待缓存完成后激活
e.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('缓存已打开,开始缓存资源');
// 批量缓存资源(Promise.all)
return cache.addAll(CACHE_ASSETS);
})
.then(function() {
// 跳过等待,直接激活(可选)
return self.skipWaiting();
})
);
});
// 2. 激活阶段:清理旧缓存
self.addEventListener('activate', function(e) {
e.waitUntil(
caches.keys().then(function(cacheNames) {
// 遍历所有缓存名称,删除旧缓存
return Promise.all(
cacheNames.map(function(cacheName) {
if (cacheName !== CACHE_NAME) {
console.log('删除旧缓存:', cacheName);
return caches.delete(cacheName);
}
})
);
}).then(function() {
// 控制所有打开的页面(可选)
return self.clients.claim();
})
);
});
// 3. 拦截请求:优先从缓存读取,缓存无则请求网络
self.addEventListener('fetch', function(e) {
e.respondWith(
caches.match(e.request)
.then(function(response) {
// 缓存中有则返回,无则请求网络
return response || fetch(e.request).catch(function() {
// 网络失败且无缓存时,返回兜底页面(可选)
return caches.match('/');
});
})
);
});
关键解析:
Service Worker 需运行在 HTTPS 或 localhost 环境下,本地开发可用 localhost;
缓存名称(CACHE_NAME):更新缓存时修改名称,触发重新安装;
缓存策略:示例为「缓存优先」,也可根据需求实现「网络优先」「缓存 + 网络」等策略。
10. HTML5 地理位置(Geolocation)+ 百度地图实战
应用场景:开发「定位服务」「附近商家」「地图应用」,结合第三方地图 API 实现可视化。
核心知识点:Geolocation 获取位置、百度地图 API 调用、坐标转换。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML5 地理位置 + 百度地图实战</title>
<style>
#map { width: 100%; height: 400px; margin: 20px 0; border: 1px solid #eee; }
.demo { max-width: 800px; margin: 0 auto; padding: 20px; }
</style>
<!-- 引入百度地图API(替换为自己的AK) -->
<script src="https://api.map.baidu.com/api?v=3.0&ak=你的百度地图AK"></script>
</head>
<body>
<div class="demo">
<h3>HTML5 定位 + 百度地图</h3>
<button onclick="getLocation()">获取我的位置</button>
<p id="locationInfo">位置信息:未定位</p>
<div id="map"></div>
</div>
<script>
const locationInfoEl = document.getElementById('locationInfo');
let map; // 百度地图实例
// 初始化百度地图
function initMap(lng, lat) {
// 创建地图实例
map = new BMapGL.Map("map");
// 设置中心点坐标(HTML5获取的是WGS84坐标,需转换为百度坐标)
const point = new BMapGL.Point(lng, lat);
// 初始化地图,设置中心点坐标和地图级别
map.centerAndZoom(point, 15);
// 开启鼠标滚轮缩放
map.enableScrollWheelZoom(true);
// 添加标记
const marker = new BMapGL.Marker(point);
map.addOverlay(marker);
// 添加信息窗口
const infoWindow = new BMapGL.InfoWindow("我的位置");
marker.addEventListener("click", function(){
map.openInfoWindow(infoWindow, point);
});
}
// 获取地理位置
function getLocation() {
// 检查浏览器是否支持Geolocation
if (!navigator.geolocation) {
locationInfoEl.innerText = '您的浏览器不支持地理位置定位';
return;
}
locationInfoEl.innerText = '正在定位...';
// 1. 获取当前位置(高精度)
navigator.geolocation.getCurrentPosition(
// 成功回调
function(position) {
const lng = position.coords.longitude; // 经度
const lat = position.coords.latitude; // 纬度
const accuracy = position.coords.accuracy; // 精度(米)
locationInfoEl.innerText = `位置信息:经度${lng.toFixed(6)},纬度${lat.toFixed(6)},精度${accuracy}米`;
// 2. 转换坐标(WGS84 → 百度坐标,需后端接口,此处简化直接使用)
// 注:实际项目需调用百度地图坐标转换API,避免偏移
initMap(lng, lat);
},
// 失败回调
function(error) {
let errorMsg = '';
switch(error.code) {
case error.PERMISSION_DENIED:
errorMsg = '用户拒绝定位权限';
break;
case error.POSITION_UNAVAILABLE:
errorMsg = '位置信息不可用';
break;
case error.TIMEOUT:
errorMsg = '定位请求超时';
break;
case error.UNKNOWN_ERROR:
errorMsg = '未知错误';
break;
}
locationInfoEl.innerText = `定位失败:${errorMsg}`;
},
// 配置项
{
enableHighAccuracy: true, // 高精度定位
timeout: 10000, // 超时时间(10秒)
maximumAge: 30000 // 缓存时间(30秒)
}
);
}
</script>
</body>
</html>
关键解析:
百度地图 AK 需要在「百度地图开放平台」申请(免费);
HTML5 获取的是 WGS84 坐标,百度地图使用 BD09 坐标,需调用坐标转换 API 避免偏移;
定位权限:需用户授权,失败时需处理多种错误场景(如用户拒绝、超时)。
总结
入门核心:语义化标签、新表单控件、多媒体标签是 HTML5 基础,需掌握「结构语义化」和「原生控件减少 JS 开发」;
进阶重点:localStorage 数据持久化、Canvas 绘图、拖放 API 是前端高频功能,需理解「事件驱动」和「数据交互」逻辑;
高级应用:Web Worker 解决主线程阻塞、Fetch 替代 AJAX、Service Worker 实现离线缓存、Geolocation 结合地图 API,需掌握「异步编程」和「跨线程通信」,同时注意浏览器兼容性和权限问题。