HTML5 是超文本标记语言(HTML)的第五个版本,发布于2014年,新增了对多媒体、图形、离线存储等功能的原生支持,同时更注重语义化和跨平台兼容性。它是用于构建和展示网页的标准技术。HTML5 引入了许多新特性和元素,以增强网页的结构和功能。以下是一些主要内容:
1.语义化标签(新增结构化标签替代传统的<div>
布局)
-
<header>
:页眉或内容头部 -
<nav>
:导航栏 -
<main>
:页面主要内容 -
<section>
:内容区块 -
<article>
:独立文章内容 -
<aside>
:侧边栏或附加内容 -
<footer>
:页脚
1.1语义化标签的核心优势
- 增强可访问性:屏幕阅读器等辅助技术能准确识别标签含义(如
<nav>
表示导航),提升残障用户的浏览体验。 - SEO 优化:搜索引擎更易解析内容结构,识别关键内容(如
<article>
内的文章),提高页面排名。 - 代码可读性与维护性:标签自解释性强(如
<header>
、<footer>
),减少对类名的依赖,便于团队协作和后期维护。 - 浏览器优化:部分标签(如
<main>
)可能触发浏览器的默认优化行为,提升渲染效率。
2.多媒体支持:HTML5 为音频和视频提供了原生支持,添加了 <audio>
和 <video>
元素,允许在网页中轻松嵌入多媒体内容,而不需要第三方插件。
2.1.video标签
直接使用 src属性时,只能加载单个视频源。推荐通过 <source>标签支持多格式兼容,解决浏览器兼容性问题 <video src="video.mp4" controls>您的浏览器不支持 HTML5 视频。 </video> <video controls><source src="video.mp4" type="video/mp4"><source src="video.webm" type="video/webm"> </video>
controls
:显示浏览器默认播放控件(播放/暂停、进度条、音量等)。
autoplay
:自动播放(受浏览器策略限制,通常需静音)。
muted
:默认静音。
loop
:循环播放。
poster
:视频封面图(未播放时显示的图像)。
preload
:预加载策略(auto|metadata|none
)。
width
/height
:设置视频显示尺寸。移动端优化
延迟加载:使用
preload="none"
减少首屏加载时间。触控事件:处理
touchstart
事件以绕过自动播放限制。
2.2.audio标签
基础用法 <audio src="audio.mp3" controls>您的浏览器不支持 HTML5 音频。 </audio>
多格式兼容 <audio controls><source src="audio.mp3" type="audio/mpeg"><source src="audio.ogg" type="audio/ogg">您的浏览器不支持音频播放。 </audio>
controls
:显示播放控件。
autoplay
:自动播放(移动端通常禁用)。
loop
:循环播放。
preload
:预加载策略(类似<video>
)。
3.1.canvas:<canvas>
元素是前端开发中实现动态图形和复杂可视化的核心工具。
1. 创建画布
<canvas id="myCanvas" width="800" height="600">您的浏览器不支持 canvas,请升级或更换浏览器。 </canvas>
width
和height
:必须通过属性(而非 CSS)设置画布分辨率,避免拉伸失真。回退内容:在不支持
canvas
的浏览器中显示替代内容。2. 获取绘图上下文
const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); // 2D 上下文 // const gl = canvas.getContext('webgl'); // WebGL 上下文(3D)
2d
:用于 2D 绘图(路径、形状、文本、图像操作)。
webgl
:用于 3D 渲染(基于 OpenGL ES)。2D 绘图 API
矩形:
ctx.fillStyle = 'blue'; // 填充颜色 ctx.fillRect(10, 10, 100, 50); // 填充矩形(x, y, width, height) ctx.strokeStyle = 'red'; // 描边颜色 ctx.strokeRect(50, 50, 80, 30); // 描边矩形
路径:
ctx.beginPath(); ctx.moveTo(100, 100); // 起点 ctx.lineTo(200, 150); // 直线 ctx.arc(250, 250, 30, 0, Math.PI * 2); // 圆 ctx.closePath(); // 闭合路径 ctx.fill(); // 填充路径 ctx.stroke(); // 描边路径
颜色与渐变:
// 线性渐变 const gradient = ctx.createLinearGradient(0, 0, 200, 0); gradient.addColorStop(0, 'red'); gradient.addColorStop(1, 'blue'); ctx.fillStyle = gradient; ctx.fillRect(0, 0, 200, 100);// 径向渐变 const radialGrad = ctx.createRadialGradient(150, 150, 10, 150, 150, 50); radialGrad.addColorStop(0, 'white'); radialGrad.addColorStop(1, 'black');
阴影:
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'; ctx.shadowBlur = 10; ctx.shadowOffsetX = 5; ctx.shadowOffsetY = 5;
. 文本绘制
ctx.font = '20px Arial'; // 字体设置 ctx.fillStyle = 'green'; ctx.fillText('Hello Canvas', 50, 50); // 填充文本 ctx.strokeText('Hello Canvas', 50, 80); // 描边文本
. 图像操作
const img = new Image(); img.src = 'image.jpg'; img.onload = () => {// 绘制图像(支持裁剪与缩放)ctx.drawImage(img, 0, 0, 200, 100); };
3.2.svg:矢量图形,基于数学公式定义图形,无限缩放不失真,适合 Retina 屏和高分辨率设备。文件体积小(相比位图),尤其适合简单图形(如图标、LOGO)。
XML 语法
直接嵌入 HTML 或作为独立文件(
.svg
)引用。支持 CSS 样式、JavaScript 操作,与 DOM 无缝集成。
DOM 可访问性
每个图形元素(如
<path>
,<circle>
)均为 DOM 节点,支持:
事件绑定(点击、悬停等)。
动态修改属性(如
fill
,transform
)。CSS 动画/过渡。
<svg width="200" height="200" viewBox="0 0 100 100">
<!-- 矩形 -->
<rect x="10" y="10" width="50" height="30" fill="#f00" stroke="#000" stroke-width="2" />
<!-- 圆形 -->
<circle cx="70" cy="50" r="20" fill="blue" opacity="0.8" />
<!-- 路径(贝塞尔曲线) -->
<path d="M10 80 Q 50 10, 90 80 T 150 80" stroke="green" fill="none" />
</svg>
4表单增强:大大增强了表单的功能和交互性。
<input type="email">
: 用于输入电子邮件地址的字段,浏览器会对输入进行简单的格式验证。
<input type="url">
: 用于输入网址的字段,浏览器会进行格式验证。
<input type="tel">
: 用于输入电话号码的字段,虽然没有格式验证,但是在移动设备上会显示数字键盘。
<input type="number">
: 用于输入数字的字段,提供上下箭头来增减数字值。
<input type="range">
: 创建一个滑动条,用于选择数值范围。
<input type="date">
: 用于输入日期, 带有一个日期选择器。
<input type="time">
: 用于输入时间, 带有一个时间选择器。
<input type="datetime-local">
: 用于输入本地日期和时间, 带有一个选择器。
<input type="month">
: 用于选择月份和年份。
<input type="week">
: 用于选择年份中的周。
<input type="color">
: 用于选择颜色的字段, 带有颜色选择器。
5.存储技术:
5.1.本地存储 (localStorage
)
持久化存储(浏览器关闭后数据保留)
- 存储容量较大(一般为 5-10MB)
- 仅存储字符串数据
- 同源策略限制(数据仅在同源页面共享)
使用场景:用户偏好设置(如主题、字体大小),离线数据缓存(如历史搜索记录),静态资源缓存(如CSS、JS文件)
// 存储数据 localStorage.setItem('key', 'value')
// 获取数据 localStorage.getItem('key')
// 删除数据 localStorage.removeItem('key')
// 清空所有数据 localStorage.clear()
5.2.临时存储(sessionStorage)
会话级存储(标签页关闭后数据清除)
容量与
localStorage
相同。使用场景:临时表单数据(如多步骤表单的中间状态),单页应用的临时状态管理(如购物车内容
// 存储数据 sessionStorage.setItem('key', 'value')
// 获取数据 sessionStorage.getItem('key')
// 删除数据 sessionStorage.removeItem('key')
// 清空所有数据 sessionStorage.clear()
5.3.IndexedDB(取代了已废弃的Web SQL)
- 支持结构化数据存储,容量更大(通常250MB以上)
- 支持事务、索引查询和异步操作。
使用场景:
离线应用(如邮件客户端、文档编辑器)
复杂数据查询(如大型电商网站的商品数据)
需要高性能存储的场景(如实时数据分析)
// 打开数据库
const request = indexedDB.open('myDatabase', 1)request.onerror = (event) => {console.error('数据库打开失败')
}request.onsuccess = (event) => {const db = event.target.result
}// 创建对象仓库
request.onupgradeneeded = (event) => {const db = event.target.resultconst objectStore = db.createObjectStore('users', { keyPath: 'id' })objectStore.createIndex('name', 'name', { unique: false })
}// 添加数据
function addData(db, user) {const transaction = db.transaction(['users'], 'readwrite')const objectStore = transaction.objectStore('users')const request = objectStore.add(user)
}// 查询数据
function getData(db, id) {const transaction = db.transaction(['users'])const objectStore = transaction.objectStore('users')const request = objectStore.get(id)request.onsuccess = (event) => {console.log('查询结果:', event.target.result)}
}
5.4.File API
允许通过JavaScript访问本地文件系统
支持文件读取、预览和分段上传。
- 存储容量大(无固定上限)
使用场景:文件上传功能(如用户头像上传),本地文件处理(如图片裁剪、PDF预览)
// 基础文件上传:
<input type="file" id="fileInput" multiple>const fileInput = document.getElementById('fileInput')fileInput.addEventListener('change', (e) => {const files = e.target.filesfor(let file of files) {console.log('文件名:', file.name)console.log('大小:', file.size)console.log('类型:', file.type)}
})
// 图片预览:
function previewImage(file) {const reader = new FileReader()reader.onload = (e) => {const img = document.createElement('img')img.src = e.target.resultdocument.body.appendChild(img)}reader.readAsDataURL(file)
}fileInput.addEventListener('change', (e) => {const file = e.target.files[0]if(file.type.startsWith('image/')) {previewImage(file)}
})
// 拖拽上传:
<div id="dropZone">拖拽文件到这里</div>const dropZone = document.getElementById('dropZone')
dropZone.addEventListener('dragover', (e) => {e.preventDefault()
})
dropZone.addEventListener('drop', (e) => {e.preventDefault()const files = e.dataTransfer.filesfor(let file of files) {console.log('接收到文件:', file.name)}
})
// 文件切片上传:
function sliceFile(file, chunkSize = 1024 * 1024) {const chunks = []let start = 0while(start < file.size) {const chunk = file.slice(start, start + chunkSize)chunks.push(chunk)start += chunkSize}return chunks
}// 使用示例
const chunks = sliceFile(file)
chunks.forEach((chunk, index) => {const formData = new FormData()formData.append('chunk', chunk)formData.append('index', index)// 上传chunk
})
6.Geolocation API 是 HTML5 提供的获取用户地理位置的 API,可以获取经纬度、海拔、精确度等信息。(/ˌdʒiːəʊləʊˈkeɪʃ(ə)n/)
获取当前位置:
// 基本语法
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options)// 实际应用
navigator.geolocation.getCurrentPosition(// 成功回调(position) => {const latitude = position.coords.latitude // 纬度const longitude = position.coords.longitude // 经度const accuracy = position.coords.accuracy // 精确度const altitude = position.coords.altitude // 海拔const timestamp = position.timestamp // 获取时间戳},// 错误回调(error) => {switch(error.code) {case error.PERMISSION_DENIED:console.error("用户拒绝定位请求")breakcase error.POSITION_UNAVAILABLE:console.error("位置信息不可用")breakcase error.TIMEOUT:console.error("获取用户位置超时")break}},// 配置选项{enableHighAccuracy: true, // 是否高精度timeout: 5000, // 超时时间maximumAge: 0 // 缓存时间}
)// 开始监听
const watchId = navigator.geolocation.watchPosition((position) => {console.log('位置更新:', position.coords)},(error) => {console.error('监听错误:', error)}
)// 停止监听
navigator.geolocation.clearWatch(watchId)
7.应用缓存:传统AppCache(/kæʃ/) 已被废弃,当前推荐Service Worker:
// main.js
if ('serviceWorker' in navigator) {window.addEventListener('load', async () => {try {const registration = await navigator.serviceWorker.register('/sw.js', {scope: '/' // 作用域})console.log('SW 注册成功,作用域:', registration.scope)} catch (error) {console.error('SW 注册失败:', error)}})
}
// sw.js
const CACHE_NAME = 'app-v1'
const CACHE_URLS = ['/','/index.html','/styles/main.css','/scripts/app.js','/images/logo.png'
]// 安装事件
self.addEventListener('install', event => {event.waitUntil(caches.open(CACHE_NAME).then(cache => cache.addAll(CACHE_URLS)))
})// 激活事件
self.addEventListener('activate', event => {event.waitUntil(caches.keys().then(cacheNames => {return Promise.all(cacheNames.filter(name => name !== CACHE_NAME).map(name => caches.delete(name)))}))
})// 请求拦截
self.addEventListener('fetch', event => {event.respondWith(caches.match(event.request).then(response => response || fetch(event.request)))
})
// 缓存优先(Cache First):
self.addEventListener('fetch', event => {event.respondWith(caches.match(event.request).then(response => {// 命中缓存if (response) {return response}// 未命中缓存,发起网络请求return fetch(event.request).then(response => {// 检查响应if (!response || response.status !== 200) {return response}// 复制响应const responseToCache = response.clone()// 存入缓存caches.open(CACHE_NAME).then(cache => {cache.put(event.request, responseToCache)})return response})}))
})
// 网络优先(Network First):
self.addEventListener('fetch', event => {event.respondWith(fetch(event.request).then(response => {// 请求成功,更新缓存const responseToCache = response.clone()caches.open(CACHE_NAME).then(cache => {cache.put(event.request, responseToCache)})return response}).catch(() => {// 请求失败,使用缓存return caches.match(event.request)}))
})
// Stale While Revalidate:
self.addEventListener('fetch', event => {event.respondWith(caches.open(CACHE_NAME).then(cache => {return cache.match(event.request).then(response => {const fetchPromise = fetch(event.request).then(networkResponse => {cache.put(event.request, networkResponse.clone())return networkResponse})return response || fetchPromise})}))
})
// 在页面中发送消息
navigator.serviceWorker.controller.postMessage({type: 'CACHE_NEW_VERSION',payload: { version: 'v2' }
})// 在 Service Worker 中接收消息
self.addEventListener('message', event => {if (event.data.type === 'CACHE_NEW_VERSION') {// 处理消息console.log('新版本:', event.data.payload.version)}
})
// 版本控制:const VERSION = 'v1.0.0'
const CACHE_NAME = `app-${VERSION}`self.addEventListener('activate', event => {event.waitUntil(caches.keys().then(cacheNames => {return Promise.all(cacheNames.filter(name => name.startsWith('app-') && name !== CACHE_NAME).map(name => caches.delete(name)))}))
})
8.网络通信:双向实时通信的首选方案WebSockets
class WebSocketClient {constructor(url) {this.url = urlthis.ws = nullthis.reconnectAttempts = 0this.maxReconnectAttempts = 5}connect() {this.ws = new WebSocket(this.url)this.ws.onopen = () => {console.log('连接成功')this.reconnectAttempts = 0}this.ws.onmessage = (event) => {const data = JSON.parse(event.data)console.log('收到消息:', data)}this.ws.onclose = () => {console.log('连接关闭')this.reconnect()}this.ws.onerror = (error) => {console.error('WebSocket错误:', error)}}send(data) {if (this.ws && this.ws.readyState === WebSocket.OPEN) {this.ws.send(JSON.stringify(data))}}reconnect() {if (this.reconnectAttempts < this.maxReconnectAttempts) {this.reconnectAttempts++setTimeout(() => {console.log(`尝试重连 ${this.reconnectAttempts}`)this.connect()}, 1000 * this.reconnectAttempts)}}close() {if (this.ws) {this.ws.close()}}
}// 使用示例
const ws = new WebSocketClient('ws://example.com/socket')
ws.connect()
ws.send({ type: 'message', content: 'Hello' })
// 实时聊天应用:class ChatApp {constructor() {this.ws = new WebSocketClient('ws://chat.example.com')this.http = new HttpClient('https://api.example.com')}async init() {// 获取历史消息const history = await this.http.get('/chat/history')this.displayMessages(history)// 建立WebSocket连接this.ws.connect()this.ws.onmessage = this.handleNewMessage.bind(this)}async sendMessage(message) {// 发送到WebSocketthis.ws.send({type: 'chat',content: message})// 保存到服务器await this.http.post('/chat/messages', {content: message})}handleNewMessage(message) {this.displayMessage(message)}displayMessage(message) {// 显示消息的UI逻辑}
}
9.设备访问
class DeviceManager {constructor() {this.location = new LocationService()this.media = new MediaDeviceService()this.sensor = new DeviceSensorService()this.battery = new BatteryService()this.vibration = new VibrationService()this.light = new AmbientLightService()}// 设备信息收集async collectDeviceInfo() {const info = {timestamp: new Date().toISOString()}try {// 获取位置info.location = await this.location.getCurrentPosition()// 获取电池状态if (this.battery.supported) {info.battery = await this.battery.getBatteryInfo()}// 获取媒体设备info.devices = await this.media.getDevices()return info} catch (error) {console.error('设备信息收集失败:', error)throw error}}// 设备监控startMonitoring(callbacks = {}) {// 监听位置变化const watchId = this.location.watchPosition(callbacks.onLocation)// 监听设备方向this.sensor.listenOrientation(callbacks.onOrientation)// 监听电池状态this.battery.watchBattery({onChargingChange: callbacks.onBatteryCharging,onLevelChange: callbacks.onBatteryLevel})// 监听环境光if (this.light.supported) {this.light.watchLight(callbacks.onLightChange)}return watchId}
}// 使用示例
const deviceManager = new DeviceManager()// 收集设备信息
deviceManager.collectDeviceInfo().then(info => console.log('设备信息:', info)).catch(error => console.error('错误:', error))// 开始监控
deviceManager.startMonitoring({onLocation: (pos) => console.log('位置更新:', pos),onOrientation: (orient) => console.log('方向更新:', orient),onBatteryLevel: (level) => console.log('电量更新:', level),onLightChange: (lux) => console.log('光照度更新:', lux)
})