为何页面切换时JS文件重复加载执行?如何解决该报错?
问题分析与解决方案
报错原因
htmx的hx-boost="true"是通过AJAX异步加载页面内容,不会刷新整个浏览器窗口,全局作用域始终保持同一个:
- 首次加载
first.html时,test.js被执行,用let声明的players变量被加入全局作用域; - 跳转到
second.html时,htmx会解析新页面的DOM,发现里面的test.js脚本后会再次执行它; - 由于
let不允许在同一作用域重复声明同名变量,直接触发Identifier 'players' has already been declared的语法错误; - 哪怕是同一个JS文件,htmx默认也会重新执行,因为它是从新页面DOM中识别到的脚本,不会自动判断是否已加载过。
解决方法
提供几种实用的解决思路:
1. 把变量封装到局部作用域
用立即执行函数表达式(IIFE)包裹test.js的代码,让变量只存在于局部作用域,避免污染全局,自然不会出现重复声明问题:
(function() { let players = /* 你的变量初始化逻辑 */; // 其他相关代码 })();
2. 标记脚本是否已执行
在test.js开头加一个全局标志,判断脚本是否已经运行过,若已运行则直接退出:
// 检查全局标记,已加载则直接返回 if (window.testJsLoaded) return; window.testJsLoaded = true; // 后续正常代码 let players = /* 你的变量初始化逻辑 */;
3. 避免重复声明变量
如果确实需要全局变量,可以改用var(不推荐,但var允许同一作用域重复声明,会直接覆盖旧值),或者先判断变量是否存在再声明:
// 先判断变量是否未定义,再声明 if (typeof players === 'undefined') { let players = /* 你的变量初始化逻辑 */; }
4. 仅在初始页面加载脚本
既然hx-boost不会刷新页面,脚本一旦加载就会留在全局作用域里,可以只在first.html中引入test.js,second.html里移除该脚本的引入。这样跳转后不会重复执行脚本,也不会触发错误。
内容的提问来源于stack exchange,提问作者Fred Hors
相关产品推荐
相关产品推荐

