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

引入函数导致DOMContentLoaded事件触发两次的解决方法

问题分析

你遇到的问题本质是file1.js的代码被执行了两次,导致DOMContentLoaded事件监听器被注册了两次。即使监听器配置了{ once: true },两次注册的回调仍会在DOM加载完成时各自触发一次,从而出现重复打印和重复执行function2的情况。

解决方案

以下几种方法可以解决这个问题,确保function2只执行一次:

方法一:添加执行标记

在file1.js中增加一个模块级标记变量,用来判断初始化逻辑是否已经执行过:

// file1.js
let isInitialized = false;

export function function1() {}

function function2() {}

window.addEventListener('DOMContentLoaded', () => {
    if (isInitialized) return;
    isInitialized = true;
    
    console.log('dom loaded');
    function2();
}, { once: true });

这样即使file1.js的代码被执行多次,第一次执行后isInitialized会被设为true,后续的回调会直接跳过。

方法二:确保模块只加载一次

检查你的页面脚本引用方式,避免同时以普通脚本和ES模块两种方式加载file1.js:

  • 如果file2.js是通过<script type="module" src="file2.js"></script>引入的,那么file1.js会被模块系统自动加载,不需要再单独用<script src="file1.js"></script>引入它。
  • 移除页面中重复的file1.js引用,保证模块只被加载执行一次。

方法三:直接判断DOM状态执行初始化

如果DOMContentLoaded事件还未触发,也可以直接在模块加载时判断DOM状态,避免重复监听:

// file1.js
export function function1() {}

function function2() {}

function init() {
    console.log('dom loaded');
    function2();
}

// 检查DOM是否已加载完成
if (document.readyState === 'loading') {
    window.addEventListener('DOMContentLoaded', init, { once: true });
} else {
    init();
}

这种方式既处理了DOM未加载的情况,也能在DOM已加载时直接执行初始化,避免不必要的监听重复。

另外注意你的file2.js中有语法错误,import语句结尾应该用分号:

// file2.js
import { function1 } from "./file1";

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 01:16:22