You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

DOMContentLoaded事件回调无法触发,window.load正常的原因咨询

为啥DOMContentLoaded没输出,window.load却正常?

哈哈,这个问题我踩过好多次坑,核心是你没搞清楚两个事件的触发时机,再加上脚本执行顺序的影响,我给你拆解明白:

首先看你代码里的第一行:var div = document.querySelector('#red');
这行是同步执行的——浏览器一解析到它就会立刻去DOM里找#red元素。如果你的脚本是放在<head>里,或者放在<body>里但在#red元素之前,这时候DOM还没构建完,#red根本不存在,不过这只会让div变成null,不会直接让脚本挂掉。

真正的问题出在你监听DOMContentLoaded的时机太晚了
DOMContentLoaded事件只会在DOM树完全构建好的那一刻触发一次。如果你的脚本是在DOM已经构建完成之后才执行的(比如脚本放在页面最底部,或者异步加载但触发时DOM已经就绪),这时候再去加监听,事件早就触发过了,回调函数自然不会跑。

那为啥window.load能正常输出?
因为window.load要等所有页面资源(图片、样式表、外部脚本这些全算)都加载完才会触发。哪怕你的脚本在DOM构建完后执行,只要页面上还有没加载完的资源(比如一张还在加载的图片),load事件就还没触发,这时候加监听就能正常捕获到,所以控制台能看到输出。

怎么 fix 这个问题?

有两个简单靠谱的办法:

  • 把所有DOM相关的操作都塞进DOMContentLoaded的回调里,包括那行querySelector

    document.addEventListener('DOMContentLoaded',function (){
      var div = document.querySelector('#red');
      console.log('event triggered...');
    });
    

    这样不管你的脚本放哪儿,都会等DOM就绪后再执行内部代码,既不会找不到元素,也不会错过事件。

  • 把脚本标签放到<body>的最后(</body>前面),这时候脚本执行时DOM已经构建完成,其实这时候没必要再用DOMContentLoaded了,直接写执行代码就行:

    var div = document.querySelector('#red');
    console.log('DOM is ready...');
    

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

火山引擎 最新活动