HTML5

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 节点,支持:

    • 事件绑定(点击、悬停等)。

    • 动态修改属性(如 filltransform)。

    • 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表单增强:大大增强了表单的功能和交互性。

  1. <input type="email">: 用于输入电子邮件地址的字段,浏览器会对输入进行简单的格式验证。

  2. <input type="url">: 用于输入网址的字段,浏览器会进行格式验证。

  3. <input type="tel">: 用于输入电话号码的字段,虽然没有格式验证,但是在移动设备上会显示数字键盘。

  4. <input type="number">: 用于输入数字的字段,提供上下箭头来增减数字值。

  5. <input type="range">: 创建一个滑动条,用于选择数值范围。

  6. <input type="date">: 用于输入日期, 带有一个日期选择器。

  7. <input type="time">: 用于输入时间, 带有一个时间选择器。

  8. <input type="datetime-local">: 用于输入本地日期和时间, 带有一个选择器。

  9. <input type="month">: 用于选择月份和年份。

  10. <input type="week">: 用于选择年份中的周。

  11. <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.result
  const 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.files
  
  for(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.result
    document.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.files
  
  for(let file of files) {
    console.log('接收到文件:', file.name)
  }
})
// 文件切片上传:
function sliceFile(file, chunkSize = 1024 * 1024) {
  const chunks = []
  let start = 0
  
  while(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("用户拒绝定位请求")
        break
      case error.POSITION_UNAVAILABLE:
        console.error("位置信息不可用")
        break
      case 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 = url
    this.ws = null
    this.reconnectAttempts = 0
    this.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) {
    // 发送到WebSocket
    this.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)
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值