原生JavaScript实现兼容所有浏览器的DOMContentLoaded事件

作者:窗边听雨

时间:2026-10-22

浏览:471

本文介绍如何使用原生JavaScript实现兼容所有浏览器的DOMContentLoaded事件。针对标准浏览器利用addEventListener监听DOMContentLoaded事件,针对IE8及以下版本通过doScroll方法结合定时器检测DOM加载状态,确保在DOM结构加载完成后执行指定函数,提升页面加载体验。

文章目录

实现背景与需求

在使用JavaScript操作DOM元素时,通常会将获取DOM元素的代码放在window.onload=function(){}事处理函数中。然而,window.onload事件在某些场景下可能会影响用户体验,因为它需要等待所有脚本、CSS代码和图片等资源加载完毕才会触发,尤其是当页面图片数量较大时,会严重影响用户体验。因此,很多时候我们只需要在DOM结构加载完毕即可执行相关操作,jQuery的$(document).ready(function(){})实现了此功能,下面介绍如何使用原生JavaScript实现这一功能。

实现过程介绍:

标准浏览器实现方案

在标准浏览器中,使用DOMContentLoaded事件即可实现我们的需求,注册事件处理函数也非常简单。

代码如下:


addEventListener(‘DOMContentLoaded',fn,false)

低版本IE浏览器兼容方案

但IE8及更低版本的浏览器并不支持DOMContentLoaded事件,因此需要另辟蹊径来解决这一问题。

可能很多朋友认为可以根据document.onreadystatechange事件的document.readyState状态是否等于complete来判断DOM结构是否加载完毕,但经过测试发现这种方法并不能完成任务,如果页面使用iframe引入子页面,会出现问题。

解决方案如下:

低版本IE浏览器特有的doScroll方法,当DOM结构没有加载完成时,调用此方法会报错,因此可以通过定时器函数不断调用此方法,并结合try-catch语句来实现判断功能,代码如下:


eventQueue = [];
isReady = false;
isBind = false;
function domReady(fn){
 if(isReady){
  fn.call(window);
 }
 else{
  eventQueue.push(fn);
 };
 bindReady();
};
function bindReady(){
 if(isReady) return;
  if(isBind) return;
  isBind=true;
  if(window.addEventListener){
   document.addEventListener('DOMContentLoaded',execFn,false);
  }
  else if(window.attachEvent){
   doScroll();
  };
};
function doScroll(){
 try{
  document.documentElement.doScroll('left');
 }
 catch(error){
  return setTimeout(doScroll,20);
 };
 execFn();
};
function execFn(){
 if(!isReady){
  isReady=true;
  for(var index=0;i<eventQueue.length;index++){
   eventQueue[index].call(window);
  };
  eventQueue = [];
 };
};
domReady(function(){
 //code
});
domReady(function(){
 //code
});

代码详细注释与解析

代码实现了兼容所有浏览器的DOMContentLoaded效果,下面介绍它的实现过程。

一、代码注释:

(1)eventQueue = [],声明一个空数组,用来存放要执行的函数队列。

(2)isReady = false,声明一个变量并赋初值为false,如果为true则表示DOM已经加载完毕。

(3)isBind = false,声明一个变量并赋初值为false,如果为true,则表示事件处理函数绑定完毕。

(4)function domReady(fn){},此函数实现了等待DOM加载完毕再去执行fn函数的功能。

(5)if(isReady){fn.call(window);},如果变量值为true,则直接执行函数。

(6)else{eventQueue.push(fn);},将要执行的函数加入数组中。

(7)bindReady(),此函数可以实现注册事件处理函数。

(8)if(isReady) return,如果等于true,直接跳出函数,这个时候fn函数已经被执行。

(9)if(isBind) return,如果已经注册的话,同样无需进行第二次。

(10)isBind=true,将变量的值修改为true。

(11)if(window.addEventListener){document.addEventListener('DOMContentLoaded',execFn,false);},如果是标准浏览器则使用addEventListener注册事件处理函数。

(12)else if(window.attachEvent){doScroll();},如果IE8及IE8以下浏览器,调用doScroll方法实现此效果。

(13)function doScroll(){},此函数可以利用定时器函数不断地调用doScroll()函数,如果报错,则继续调用,否则的话,也就是DOM结构加载完毕,于是就执行相关函数。

(14)function execFn(){},此函数可以从数组中取出要执行的函数,然后执行,并最后将数组清空。

总结

以上所述是小编给大家介绍的JS兼容所有浏览器的DOMContentLoaded事件,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对本站网站的支持!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章