当前位置: 首页 > news >正文

第三节:HTML5 高级特性与应用​

学习 HTML5 的第三节,​​核心目标是掌握 HTML5 的“动态能力”与“浏览器原生功能”​​,即如何利用 HTML5 提供的 API 和特性,让网页从“静态文档”升级为“可交互的应用”。这一节将重点讲解 ​​客户端存储、Canvas 绘图、拖放交互、地理定位​​ 等实用技术,帮助你理解 HTML5 如何扩展网页的能力边界。


​​​​学习目标​

  1. 掌握客户端存储的两种方案(Web StorageIndexedDB),解决 Cookie 的局限性。
  2. 学会使用 Canvas 绘制图形、实现动画,替代传统的 Flash 或图片。
  3. 理解拖放(Drag & Drop)API 的原理,实现文件上传或列表排序。
  4. 掌握地理定位(Geolocation)API,获取用户位置信息。

​一、客户端存储:从 Cookie 到 Web Storage/IndexedDB​

传统 Cookie 存储存在​​大小限制(约 4KB)、随 HTTP 请求发送(增加流量)、安全性低(易被篡改)​​ 等问题。HTML5 提供了更强大的存储方案:Web StoragelocalStorage/sessionStorage)和 IndexedDB

​1. Web Storage:轻量级键值对存储​

Web Storage 是浏览器提供的本地存储机制,分为两种:

  • localStorage:持久化存储(清除浏览器缓存前一直存在)。
  • sessionStorage:会话级存储(关闭标签页后失效)。
​核心操作​
操作代码示例说明
存储数据localStorage.setItem('user', JSON.stringify({ name: '张三' }))存储对象需用 JSON.stringify 转为字符串
读取数据const user = JSON.parse(localStorage.getItem('user'))读取时用 JSON.parse 转回对象
删除单个键localStorage.removeItem('user')
清空所有数据localStorage.clear()
监听存储变化window.addEventListener('storage', (e) => { ... })其他标签页修改存储时触发(仅 localStorage
​示例:用 localStorage 实现“主题切换”​

需求:用户点击按钮切换暗/亮模式,下次打开页面时保持上次选择的主题。

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>主题切换示例</title><style>body.light {background: #fff;color: #333;}body.dark {background: #333;color: #fff;}button {padding: 10px 20px;cursor: pointer;}</style>
</head>
<body class="light"><h2>主题切换</h2><button id="themeBtn">切换为暗模式</button><script>const btn = document.getElementById('themeBtn');const body = document.body;// 读取本地存储的主题设置const savedTheme = localStorage.getItem('theme');if (savedTheme) {body.className = savedTheme;btn.textContent = savedTheme === 'dark' ? '切换为亮模式' : '切换为暗模式';}// 点击按钮切换主题btn.addEventListener('click', () => {if (body.className === 'light') {body.className = 'dark';localStorage.setItem('theme', 'dark'); // 存储主题btn.textContent = '切换为亮模式';} else {body.className = 'light';localStorage.setItem('theme', 'light'); // 存储主题btn.textContent = '切换为暗模式';}});</script>
</body>
</html>
​Web Storage 的局限性​
  • 仅支持存储字符串(对象需序列化)。
  • 存储容量有限(通常 5-10MB,不同浏览器不同)。
  • 无法存储结构化数据(如数组、嵌套对象)。
​2. IndexedDB:结构化数据存储​

IndexedDB 是浏览器提供的​​本地数据库​​,支持存储大量结构化数据(如对象、数组)、索引查询、事务操作,适合离线应用或需要复杂查询的场景(如待办事项列表、笔记应用)。

​核心概念​
  • ​数据库(Database)​​:存储数据的容器,需指定名称和版本。
  • ​对象仓库(Object Store)​​:类似“表”,存储同类型的对象(如 todos 存储待办事项)。
  • ​索引(Index)​​:为对象仓库的某个属性创建索引,加速查询(如按 completed 状态查询待办事项)。
​示例:用 IndexedDB 存储“待办事项”​

需求:添加、删除待办事项,支持按“已完成”筛选。

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>IndexedDB 待办事项</title><style>.todo-input { margin: 10px 0; padding: 5px; }.todo-item { padding: 8px; margin: 5px 0; border: 1px solid #ddd; }.completed { text-decoration: line-through; color: #999; }</style>
</head>
<body><h2>待办事项(IndexedDB)</h2><input type="text" class="todo-input" id="todoInput" placeholder="输入待办事项"><button onclick="addTodo()">添加</button><div id="todoList"></div><script>let db;const DB_NAME = 'TodoDB';const STORE_NAME = 'todos';// 打开/创建数据库const request = indexedDB.open(DB_NAME, 1);// 数据库首次创建或版本升级时触发request.onupgradeneeded = (e) => {db = e.target.result;// 创建对象仓库(类似表),并设置主键为自增 idif (!db.objectStoreNames.contains(STORE_NAME)) {const store = db.createObjectStore(STORE_NAME, { keyPath: 'id', autoIncrement: true });// 为 completed 属性创建索引,用于查询store.createIndex('completed', 'completed', { unique: false });}};// 数据库打开成功request.onsuccess = (e) => {db = e.target.result;loadTodos(); // 加载已有的待办事项};// 添加待办事项function addTodo() {const input = document.getElementById('todoInput');const text = input.value.trim();if (!text) return;const todo = { text, completed: false };const transaction = db.transaction(STORE_NAME, 'readwrite');const store = transaction.objectStore(STORE_NAME);store.add(todo); // 插入数据input.value = '';loadTodos(); // 刷新列表}// 加载待办事项并渲染function loadTodos() {const transaction = db.transaction(STORE_NAME, 'readonly');const store = transaction.objectStore(STORE_NAME);const index = store.index('completed'); // 使用索引查询const request = index.getAll(); // 获取所有待办事项request.onsuccess = (e) => {const todos = e.target.result;const list = document.getElementById('todoList');list.innerHTML = ''; // 清空旧内容todos.forEach(todo => {const item = document.createElement('div');item.className = `todo-item ${todo.completed ? 'completed' : ''}`;item.innerHTML = `<input type="checkbox" onchange="toggleTodo(${todo.id}, this.checked)"><span>${todo.text}</span><button onclick="deleteTodo(${todo.id})">删除</button>`;list.appendChild(item);});};}// 切换待办事项状态function toggleTodo(id, completed) {const transaction = db.transaction(STORE_NAME, 'readwrite');const store = transaction.objectStore(STORE_NAME);store.get(id).onsuccess = (e) => {const todo = e.target.result;todo.completed = completed;store.put(todo); // 更新数据loadTodos(); // 刷新列表};}// 删除待办事项function deleteTodo(id) {const transaction = db.transaction(STORE_NAME, 'readwrite');const store = transaction.objectStore(STORE_NAME);store.delete(id); // 删除数据loadTodos(); // 刷新列表}</script>
</body>
</html>
​IndexedDB 的优势​
  • 支持存储大量数据(通常无严格大小限制)。
  • 支持索引查询(如按 completed 筛选),查询效率高。
  • 支持事务(保证数据操作的原子性,避免部分失败)。

​二、Canvas:动态绘图与动画​

<canvas> 是 HTML5 提供的“位图容器”,通过 JavaScript 动态绘制图形(如线条、矩形、圆),适合实现图表、游戏、动画等需要“像素级控制”的场景。

​核心步骤​
  1. ​在 HTML 中添加 <canvas> 标签​​:

    <canvas id="myCanvas" width="800" height="600"></canvas>
    • widthheight 定义画布的实际像素尺寸(与 CSS 样式中的宽高不同)。
  2. ​通过 JavaScript 获取绘图上下文​​:

    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d'); // 2D 绘图上下文(支持 2D 图形)
  3. ​使用上下文对象绘制图形​​:

    • 绘制路径(beginPath()moveTo()lineTo()arc())。
    • 设置样式(颜色、线条粗细、填充色)。
    • 填充或描边(fill()stroke())。
​示例:绘制一个旋转的小球(动画)​
<!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 #ddd; }</style>
</head>
<body><canvas id="myCanvas" width="600" height="400"></canvas><script>const canvas = document.getElementById('myCanvas');const ctx = canvas.getContext('2d');let angle = 0; // 旋转角度(弧度)function drawBall() {// 清空画布(用白色覆盖)ctx.fillStyle = '#fff';ctx.fillRect(0, 0, canvas.width, canvas.height);// 绘制小球const centerX = canvas.width / 2; // 画布中心 X 坐标const centerY = canvas.height / 2; // 画布中心 Y 坐标const radius = 50; // 小球半径const ballX = centerX + Math.cos(angle) * radius; // 小球 X 坐标(随角度旋转)const ballY = centerY + Math.sin(angle) * radius; // 小球 Y 坐标(随角度旋转)// 开始绘制路径ctx.beginPath();ctx.arc(ballX, ballY, 20, 0, Math.PI * 2); // 绘制圆(半径 20)ctx.fillStyle = '#ff4757'; // 填充颜色ctx.fill();// 更新角度(每次增加 0.05 弧度)angle += 0.05;// 递归调用,实现动画(约 60 帧/秒)requestAnimationFrame(drawBall);}// 启动动画drawBall();</script>
</body>
</html>
​关键说明​
  • requestAnimationFrame:浏览器提供的动画 API,比 setInterval 更高效(自动适配屏幕刷新率)。
  • 坐标系统:画布左上角为原点 (0,0),向右为 X 轴正方向,向下为 Y 轴正方向。
  • 绘制顺序:后绘制的图形会覆盖先绘制的图形(如清空画布后再绘制小球)。

​三、拖放(Drag & Drop)API​

拖放 API 允许用户通过鼠标拖拽元素(如文件、列表项),并与页面交互(如上传文件、排序列表)。

​核心步骤​
  1. ​标记可拖拽元素​​:
    给需要拖拽的元素添加 draggable="true" 属性。

  2. ​监听拖拽事件​​:

    • dragstart:开始拖拽时触发(设置被拖拽的数据)。
    • dragover:拖拽元素经过目标元素时触发(需阻止默认行为以允许放置)。
    • drop:拖拽元素释放到目标元素时触发(处理放置逻辑)。
​示例:文件拖放上传​

需求:用户将本地文件拖拽到页面指定区域,显示文件名和大小。

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>文件拖放上传</title><style>.drop-zone {width: 400px;height: 200px;border: 2px dashed #ccc;display: flex;align-items: center;justify-content: center;margin: 20px auto;}.file-info {margin-top: 10px;padding: 10px;border: 1px solid #eee;}</style>
</head>
<body><h2>文件拖放上传</h2><div class="drop-zone" id="dropZone">拖拽文件到此处上传</div><div class="file-info" id="fileInfo"></div><script>const dropZone = document.getElementById('dropZone');const fileInfo = document.getElementById('fileInfo');// 阻止浏览器默认的拖放行为(如打开文件)['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {dropZone.addEventListener(eventName, preventDefaults, false);document.body.addEventListener(eventName, preventDefaults, false);});// 高亮拖放区域(当文件被拖拽到上方时)['dragenter', 'dragover'].forEach(eventName => {dropZone.addEventListener(eventName, highlight, false);});['dragleave', 'drop'].forEach(eventName => {dropZone.addEventListener(eventName, unhighlight, false);});// 处理文件放置dropZone.addEventListener('drop', handleDrop, false);function preventDefaults(e) {e.preventDefault();e.stopPropagation();}function highlight() {dropZone.style.borderColor = '#ff4757';dropZone.style.backgroundColor = '#f8f9fa';}function unhighlight() {dropZone.style.borderColor = '#ccc';dropZone.style.backgroundColor = '';}function handleDrop(e) {const dt = e.dataTransfer; // 拖放数据对象const files = dt.files; // 获取拖放的文件列表if (files.length > 0) {fileInfo.innerHTML = '<h3>上传的文件:</h3>';for (const file of files) {const fileInfoItem = document.createElement('div');fileInfoItem.textContent = `文件名:${file.name},大小:${file.size} 字节`;fileInfo.appendChild(fileInfoItem);}}}</script>
</body>
</html>
​关键说明​
  • dataTransfer 对象:存储拖拽过程中传递的数据(如文件、文本)。
  • preventDefaults():阻止浏览器默认行为(如拖放文件时直接打开)。
  • highlight()unhighlight():通过改变样式提示用户可放置区域。

​四、地理定位(Geolocation)API​

地理定位 API 允许网页获取用户的地理位置信息(需用户授权),适用于地图应用、附近服务推荐等场景。

​核心方法​

navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options)

  • successCallback:获取位置成功时触发的回调函数(参数为 Position 对象)。
  • errorCallback:获取位置失败时触发的回调函数(参数为 PositionError 对象)。
  • options:可选配置(如 enableHighAccuracy 启用高精度,timeout 超时时间)。
​示例:获取用户位置并显示经纬度​
<!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><h2>您的位置信息</h2><div id="locationInfo"></div><script>const locationInfo = document.getElementById('locationInfo');if (!navigator.geolocation) {locationInfo.textContent = '您的浏览器不支持地理定位!';} else {navigator.geolocation.getCurrentPosition((position) => {const latitude = position.coords.latitude; // 纬度const longitude = position.coords.longitude; // 经度const accuracy = position.coords.accuracy; // 精度(米)locationInfo.innerHTML = `<p>纬度:${latitude.toFixed(6)}</p><p>经度:${longitude.toFixed(6)}</p><p>精度:约 ${Math.round(accuracy)} 米</p>`;},(error) => {let message = '';switch (error.code) {case error.PERMISSION_DENIED:message = '您拒绝了位置权限请求!';break;case error.POSITION_UNAVAILABLE:message = '无法获取位置信息!';break;case error.TIMEOUT:message = '获取位置超时!';break;}locationInfo.textContent = message;},{enableHighAccuracy: true, // 启用高精度(可能更耗电)timeout: 10000 // 10 秒超时});}</script>
</body>
</html>
​关键说明​
  • 用户授权:首次调用时会弹出提示框,用户需允许后才能获取位置。
  • 精度:accuracy 表示位置的误差范围(值越小越精确,GPS 定位通常误差在 5-10 米)。

​五、第三节的实践任务​

为了巩固第三节的知识,完成以下练习:

​任务 1:用 IndexedDB 实现“便签应用”​

要求:

  • 添加便签(标题、内容)。
  • 编辑便签(双击修改)。
  • 删除便签(点击删除按钮)。
  • 数据存储在 IndexedDB 中,刷新页面后保留。
​任务 2:用 Canvas 绘制“简易图表”​

要求:

  • 绘制一个柱状图,展示一周的天气温度(模拟数据)。
  • 每个柱子上方显示具体温度值。
​任务 3:用拖放 API 实现“任务排序”​

要求:

  • 页面有多个任务项(如“学习 HTML5”“完成项目”)。
  • 拖拽任务项可以调整它们的顺序。
  • 顺序变化后,控制台输出新的顺序。

​总结​

第三节的核心是​​掌握 HTML5 的高级特性​​:

  • ​客户端存储​​:用 Web Storage 解决轻量数据存储,用 IndexedDB 处理复杂结构化数据。
  • ​Canvas​​:通过 JavaScript 动态绘制图形和动画,替代传统图片或 Flash。
  • ​拖放交互​​:实现文件上传、列表排序等用户友好的交互功能。
  • ​地理定位​​:获取用户位置信息,开发基于位置的服务。

​学习建议​​:动手编写每个任务的代码,结合浏览器开发者工具(F12)调试存储、绘图和事件。遇到问题时,查阅 MDN 文档 确认 API 的正确用法。通过实践,你会更深刻地理解 HTML5 如何让网页“活起来”!


文章转载自:

http://fsPbBRZN.grtwn.cn
http://D63r2DQt.grtwn.cn
http://7JVJnrLU.grtwn.cn
http://sJmZXePb.grtwn.cn
http://i7vbfoHW.grtwn.cn
http://NZDJXSmd.grtwn.cn
http://JpVQqsoE.grtwn.cn
http://AXaSkvPQ.grtwn.cn
http://7ToGCPHe.grtwn.cn
http://OmGIITSX.grtwn.cn
http://ac08xkCu.grtwn.cn
http://HFXU3sEo.grtwn.cn
http://1FrK8Loo.grtwn.cn
http://cYRFpxHr.grtwn.cn
http://lxuiaci5.grtwn.cn
http://gXf6bNDD.grtwn.cn
http://6Uk96K29.grtwn.cn
http://VmAgkdFX.grtwn.cn
http://9PkfR1YW.grtwn.cn
http://HRamGN4d.grtwn.cn
http://oW7y9WOd.grtwn.cn
http://qOTXVFMv.grtwn.cn
http://KBbMJLXv.grtwn.cn
http://XlkUH6tj.grtwn.cn
http://164Wimee.grtwn.cn
http://BBqAhc6N.grtwn.cn
http://GRlP4tqv.grtwn.cn
http://m71Ee0jZ.grtwn.cn
http://2dQaITlR.grtwn.cn
http://AmVumlXQ.grtwn.cn
http://www.dtcms.com/a/370527.html

相关文章:

  • 【C++】模板和STL
  • react生命周期,详细版本
  • NLWeb与AutoRAG跨境电商RAG推荐API接入实战教程
  • Storybook:多框架兼容的前端组件开发工具,高效解决组件隔离开发与文档管理问题
  • 嵌入式笔记系列——UART:TTL-UART、RS-232、RS-422、RS-485
  • Week 15: 深度学习补遗:集成学习初步
  • 计算机CPU的工作原理介绍
  • 科学研究系统性思维的方法体系:个人研究项目管理
  • macbook intel 打开cursor会闪退
  • Day22_【机器学习—集成学习(2)—Bagging—随机森林算法】
  • 2025年大数据专业人士认证发展路径分析
  • 【CV】Opencv图像处理——①几何变换 (1)
  • dify+Qwen2.5-vl+deepseek打造属于自己的作业帮
  • 待定系数法分解分式
  • WordPress过滤文章插入链接rel属性noopener noreferrer值
  • AwesomeBump Windows上编译细则
  • 2026届大数据毕业设计选题推荐-基于大数据旅游数据分析与推荐系统 爬虫数据可视化分析
  • NIOS ii工程移植路径问题
  • Redis中的List数据类型
  • 设计一个 AB 测试平台
  • MATLAB2025-安装Embedded Code Support Pacjage for STM32 Processors
  • 去中心化投票系统开发教程 第三章:智能合约设计与开发
  • 基于Matlab的MEMS陀螺仪Allan方差分析与随机误差参数识别
  • 植物大战僵尸融合版安装包,下载安装教程
  • 基于STM32的智能宠物屋系统设计
  • SQL 入门指南:排序与分页查询(ORDER BY 多字段排序、LIMIT 分页实战)
  • (算法 哈希表)【LeetCode 349】两个数组的交集 思路笔记自留
  • 【PCIe EP 设备入门学习专栏 -- 8.1.3 PCIe EP AXI Bridge Module】
  • MySQL集群高可用架构(MHA高可用架构)
  • 多线程任务执行窗体框架jjychengTaskWinForm