HTML5 脚本

张开发
2026/6/6 19:53:36 15 分钟阅读
HTML5 脚本
HTML5 脚本学习笔记HTML5 对 JavaScript 脚本的处理进行了重大改进旨在提高页面加载性能、优化执行顺序并增强脚本与 HTML 的交互能力。核心变化集中在script标签的新属性、异步加载策略以及新的 API 支持上。一、script标签的新属性HTML5 引入了两个关键属性来控制脚本的加载和执行时机async和defer。它们解决了传统脚本阻塞 HTML 解析的问题。1. 传统模式 (无属性)scriptsrcapp.js/script行为浏览器遇到标签时立即停止HTML 解析下载并执行脚本执行完才继续解析 HTML。缺点导致页面渲染阻塞用户看到“白屏”时间变长。2.defer(延迟执行)scriptsrcapp.jsdefer/script行为脚本并行下载不阻塞 HTML 解析。脚本在HTML 解析完成后按顺序执行。保证多个defer脚本的执行顺序与它们在文档中的出现顺序一致。适用场景需要操作 DOM 的脚本如初始化页面逻辑、事件绑定且依赖 DOM 结构已完全加载。推荐现代开发中大多数非关键脚本应使用defer。3.async(异步执行)scriptsrcanalytics.jsasync/script行为脚本并行下载不阻塞 HTML 解析。脚本下载完成后立即执行此时 HTML 解析会暂停。不保证多个async脚本的执行顺序谁先下载完谁先执行。适用场景独立的脚本不依赖 DOM也不依赖其他脚本如统计代码、广告脚本、社交插件。注意如果脚本之间有依赖关系不要使用async。4. 属性对比表特性默认 (无属性)deferasync阻塞解析是否否执行时机立即下载执行DOM 解析完成后下载完成后立即执行执行顺序顺序顺序无序 (取决于下载速度)依赖关系支持支持不支持 (独立脚本)典型用途旧代码主应用逻辑、DOM 操作统计、广告、第三方插件二、脚本加载的最佳实践1. 放置位置HTML5 推荐将script标签放在body的底部/body之前或者使用defer放在head中。原因确保 HTML 结构先被解析避免脚本操作未存在的 DOM 元素。!-- 推荐做法放在 body 底部 --bodydividapp内容/div!-- 使用 defer 放在 head 也是推荐的 --scriptsrcmain.jsdefer/script/body2. 模块化脚本 (typemodule)HTML5 原生支持 ES6 模块无需第三方库如 RequireJS。scripttypemodulesrcmain.js/script特性默认具有defer行为异步加载DOM 解析后执行。脚本在严格模式(use strict) 下运行。变量作用域是模块级的不会污染全局命名空间。支持import/export。跨域模块脚本必须设置crossorigin属性如果涉及跨域 CORS。// main.jsimport{sayHello}from./utils.js;sayHello();3. 内联脚本优化避免过长的内联脚本尽量使用外部文件以便缓存。如果必须内联使用nonce属性配合 CSP (内容安全策略) 提高安全性。scriptnonce随机字符串console.log(安全内联脚本);/script三、HTML5 脚本相关的新 APIHTML5 不仅改进了标签还引入了许多新的 JavaScript API让脚本能更强大地与浏览器交互。1. 历史管理 (historyAPI)允许在不刷新页面的情况下修改浏览器历史记录实现单页应用 (SPA) 的导航。// 添加历史记录history.pushState({page:1},标题,/page1);// 修改当前历史记录history.replaceState({page:2},标题,/page2);// 监听浏览器前进/后退window.addEventListener(popstate,function(event){console.log(用户点击了前进/后退,event.state);});2. 本地存储 (localStoragesessionStorage)替代 Cookie提供更大的存储空间通常 5MB和更简单的 API。// 存储数据 (字符串)localStorage.setItem(username,Alice);sessionStorage.setItem(token,xyz123);// 读取数据constuserlocalStorage.getItem(username);// 删除数据localStorage.removeItem(username);// 清空localStorage.clear();3. 网络状态 (navigator.onLine)检测用户是否在线。window.addEventListener(online,()console.log(已连接网络));window.addEventListener(offline,()console.log(已断开网络));if(navigator.onLine){console.log(当前在线);}4. 拖放 API (Drag and Drop)原生支持元素拖拽无需 jQuery UI。dividdragmedraggabletrue拖我/divdividdropzone放下区域/divscriptconstdragdocument.getElementById(dragme);constdropdocument.getElementById(dropzone);drag.addEventListener(dragstart,(e){e.dataTransfer.setData(text/plain,拖拽数据);});drop.addEventListener(dragover,(e){e.preventDefault();// 允许放置});drop.addEventListener(drop,(e){e.preventDefault();constdatae.dataTransfer.getData(text/plain);drop.textContent收到data;});/script5. Canvas 绘图通过脚本在canvas上绘制图形、动画和游戏。constcanvasdocument.getElementById(myCanvas);constctxcanvas.getContext(2d);ctx.fillStylered;ctx.fillRect(10,10,100,100);6. Web Workers (多线程)允许在后台运行脚本不阻塞 UI 渲染。// main.jsconstworkernewWorker(worker.js);worker.postMessage(开始计算);worker.onmessagefunction(e){console.log(结果:,e.data);};// worker.jsself.onmessagefunction(e){constresultheavyCalculation();self.postMessage(result);};四、脚本安全与 CSP (内容安全策略)HTML5 强调脚本安全通过 CSP 防止 XSS 攻击。metahttp-equivContent-Security-Policycontentdefault-src self; script-src self https://trusted-cdn.com;作用限制脚本只能从指定域名加载禁止内联脚本除非使用nonce或hash。最佳实践尽量使用外部脚本文件。避免eval()和new Function()。对用户输入进行转义。五、实战现代脚本加载策略!DOCTYPEhtmlhtmllangzh-CNheadmetacharsetUTF-8titleHTML5 脚本策略/title!-- 1. 第三方统计 (async) --scriptasyncsrchttps://www.googletagmanager.com/gtag/js?idGA_ID/script!-- 2. 核心逻辑 (defer) --scriptsrcapp.jsdefer/script!-- 3. 模块化脚本 (typemodule 隐含 defer) --scripttypemodulesrcmain-module.js/script/headbodyh1HTML5 脚本演示/h1dividcontent加载中.../div!-- 4. 内联脚本 (仅用于初始化尽量短) --scriptconsole.log(页面开始加载);// 避免操作 DOM因为此时 DOM 可能未就绪/script/body/html六、总结与注意事项优先使用defer对于大多数需要操作 DOM 的脚本defer是最佳选择既保证性能又保证执行顺序。独立脚本用async统计、广告等不依赖 DOM 和其他脚本的代码使用async。拥抱模块化使用typemodule利用 ES6 模块系统代码更清晰、可维护性更高。避免阻塞永远不要让脚本阻塞 HTML 解析除非脚本必须立即执行且非常短。安全至上实施 CSP 策略避免内联脚本防止 XSS 攻击。兼容性async/defer在现代浏览器中支持良好但在极老的浏览器如 IE9 以下中可能无效需考虑降级方案如动态插入脚本。掌握这些 HTML5 脚本特性能显著提升网页的加载速度、用户体验和代码质量

更多文章