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

导入含异步数据的模块后,DOMContentLoaded与load事件未触发

问题:导入含顶级await的模块后,DOMContentLoaded/load事件监听失效

问题原因

  • ES模块默认异步加载,再加上你的test.js里用了顶级await(let test = await f();),模块执行会等待异步请求完成才继续。
  • 等模块执行到添加事件监听的代码时,DOMContentLoaded甚至load事件可能已经触发完了——浏览器在加载模块的这段时间里,DOM可能早就解析完成,页面资源也加载好了,事件触发过一次后,后续再添加监听就不会触发回调了。
  • 而jQuery的$(document).ready()能正常工作,是因为它内部会先检查DOM是否已经就绪,如果已经就绪,会直接执行回调,不是只靠事件监听。

解决方案

方案1:先加事件监听,再导入模块

把事件监听代码放在import语句前面,确保在DOM事件触发前就完成监听:

<head>
    <script type="module">
        // 先注册事件监听
        window.addEventListener("DOMContentLoaded", () => {
            console.log("DOMContentLoaded");
        });

        window.addEventListener("load", () => {
            console.log("load");
        });

        // 再导入模块
        import test from "/js/test.js";
        console.log(test);

        $(document).ready(() => {
            console.log("ready"); 
        });
    </script>
</head>

方案2:主动检查事件是否已触发

通过document.readyState判断当前DOM状态,如果事件已经触发过,就直接执行回调,否则再添加监听:

// 处理DOMContentLoaded
if (document.readyState === "interactive" || document.readyState === "complete") {
    console.log("DOMContentLoaded");
} else {
    window.addEventListener("DOMContentLoaded", () => {
        console.log("DOMContentLoaded");
    });
}

// 处理load事件
if (document.readyState === "complete") {
    console.log("load");
} else {
    window.addEventListener("load", () => {
        console.log("load");
    });
}

方案3:修改模块逻辑,移除顶级await

把test.js里的顶级await改成导出Promise,在主模块里等待这个Promise,同时提前设置事件监听:

// 修改后的test.js
async function f() {
    const r = await fetch("url", {
        method: "post",
        body: JSON.stringify({
            "key": "value"
        }),
        headers: {
            "Content-Type": "application/json",
            "Accept": "application/json",
        }
    })
    .then(res => res.json())
    .then(result => result);
    return r;
}

export default f(); // 导出一个Promise
<!-- 修改后的main.js -->
<head>
    <script type="module">
        // 先注册事件监听
        window.addEventListener("DOMContentLoaded", () => {
            console.log("DOMContentLoaded");
        });

        window.addEventListener("load", () => {
            console.log("load");
        });

        import testPromise from "/js/test.js";
        // 等待Promise完成后处理数据
        testPromise.then(test => {
            console.log(test);
        });

        $(document).ready(() => {
            console.log("ready"); 
        });
    </script>
</head>

内容的提问来源于stack exchange,提问作者D L

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 05:48:22