← 全部文章

教程

“仅运行一次 JS”——在 SPA 页面上无副作用的脚本

在单页应用(SPA)页面上,JustZix 会在每次地址变化后重新运行规则集的 JavaScript——以便规则处理刚刚渲染出来的视图。对大多数脚本来说这是好事。但对于带有全局副作用的脚本,这会导致不断累积。新的“仅运行一次 JS”选项解决了这个问题。

问题:脚本被一遍遍运行

SPA 在不重新加载文档的情况下改变内容。JustZix 会检测到这类导航并再次运行规则集的 JS,让规则在新视图上生效。但如果脚本添加了事件监听器、设置了定时器(setInterval),或者“包装”了某个页面函数(例如 window.fetchdataLayer.push),那么每一次重新运行都会再添加一个副本。几次切换之后,你就有了五个相同的监听器、五个并行的定时器,以及一个被包装了五层的函数。

解决办法:“仅运行一次 JS”复选框

规则集编辑器的 JavaScript 选项卡现在多了一个“仅运行一次 JS”的字段(默认关闭——对现有规则集没有任何改变)。勾选后——规则集的 JS 在文档的整个生命周期内只运行一次。SPA 导航、#hash 变化和后退按钮都不会再次运行它。整页重新加载则始终是一次全新的开始。

什么时候勾选它

对以下这些脚本开启“仅运行一次 JS”:

什么时候保持关闭

对于那些本就该对每一个 SPA 子视图作出反应的脚本,请保持该选项关闭——例如每次都去查找刚刚渲染出来的元素并对它们做些处理的脚本。如果你的脚本是幂等的(多次运行也安全),那你同样不需要改动任何东西。

良好实践:编写幂等代码

不论这个选项如何,编写能够经受重复运行的脚本都是值得的。一个简单的写法是用一个守卫,在脚本已经运行过一次时就中止它:

// 守卫:每个文档只执行一次逻辑
if (!window.__jzMyScript) {
  window.__jzMyScript = true;
  document.addEventListener('keydown', onKey);
}

“仅运行一次 JS”选项和代码中的守卫是同一种保护的两道防线——你可以同时使用它们。

安装 JustZix,编写能在 SPA 上运行而不会让副作用层层累积的脚本。

为这篇文章评分

暂无评分 — 成为第一个。

自己动手试试

安装 JustZix,粘贴本文中的任意代码片段。两分钟,从零到一条在你所有设备上生效的规则。

获取 JustZix

功能 · 工作原理 · 示例 · 应用场景