You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

fetch动态加载HTML插入type='module'脚本仅首次生效后续不执行问题

问题原因

ES 模块规范默认对相同URL的模块只会执行一次顶层代码,后续无论你多少次插入相同src的type="module"脚本标签,浏览器都会复用已经缓存的模块实例,不会重新执行模块内的代码。普通脚本没有这个限制,所以你之前没加模块属性的时候运行正常。
你之前尝试的动态导入方案没有生效,是因为你把动态导入的逻辑还是写在了page_1.js的顶层,模块第一次执行后顶层代码不会重复运行,自然也就不会触发后续的执行逻辑。

解决方案

方案1:给脚本URL加随机参数强制不缓存

这是最简单的适配方案,不需要修改原有模块的代码,只需要在加载脚本时给URL拼接时间戳或者随机数,让浏览器认为每次都是不同的资源,就会重新执行:

function loadHTML(htmlPath) {
  fetch(`pages/${htmlPath}.html`)
    .then((res) => res.text())
    .then((html) => {
      let page_content = document.querySelector("#page_content");
      page_content.innerHTML = html;
      let script = document.createElement("script");
      // 拼接时间戳,规避模块缓存
      script.src = `pages/${htmlPath}.js?t=${Date.now()}`;
      if (htmlPath === "page_1") {
        script.type = "module";
      }
      page_content.appendChild(script);
    });
}

这个方案的缺点是模块文件不会被浏览器缓存,每次加载都要重新请求,如果你的脚本体积不大的话完全可以忽略这个影响。

方案2:调整模块结构,导出初始化函数主动调用

如果想要保留模块缓存的优势,避免重复请求,可以把模块中原先写在顶层的执行逻辑封装成一个导出的函数,每次加载页面的时候主动调用这个函数即可:
首先修改page_1.js的代码:

import { displayConsoleMSG } from "../functions/someFunc.js";
// 把原来的顶层逻辑封装成init函数导出
export function init() {
  displayConsoleMSG("test");
  // 其他原来需要每次加载页面都执行的逻辑都放到这里
}

然后修改main.js的加载逻辑,针对模块脚本使用动态导入并调用初始化函数:

function loadHTML(htmlPath) {
  fetch(`pages/${htmlPath}.html`)
    .then((res) => res.text())
    .then(async (html) => {
      let page_content = document.querySelector("#page_content");
      page_content.innerHTML = html;
      if (htmlPath === "page_1") {
        // 动态导入模块,调用初始化函数
        const pageModule = await import(`./pages/${htmlPath}.js`);
        pageModule.init();
      } else {
        // 普通脚本保持原有逻辑
        let script = document.createElement("script");
        script.src = `pages/${htmlPath}.js`;
        page_content.appendChild(script);
      }
    });
}

这个方案既保留了模块的缓存优势,也能保证每次切换页面都能执行对应逻辑,更符合ES模块的最佳实践。

内容的提问来源于stack exchange,提问作者Kleber Germano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 06:54:02