原生JS实现DOM加载完成马上执行JS代码的方法


Posted in Javascript onSeptember 07, 2018

用原生JS我们经常使用window.onload事件来加载页面。但是window.onload是在页面元素都加载完毕后才执行,如果页面内有大的图片的话,会在页面展现后好久时间后才执行。所以有时我们需要在DOM载入时马上执行一些函数。jQuery提供了document.ready方法用来代替window.onload。但又不愿意仅为了这一个需求而引入整个JQuery库,于是就把jQuery的方法提取出来,单独使用了。

如果只需要对DOM进行操作,那么这时就没必要等到页面全部加载了。Firefox有DOMContentLoaded事件可以轻松解决,可惜的就是IE没有。

MSDN关于JSCRIPT的一个方法有段不起眼的话,当页面DOM未加载完成时,调用doScroll方法时,会产生异常。那么我们反过来用,如果不异常,那么就是页面DOM加载完毕了。所以 对于Mozilla & Opera 浏览器,在dom树载入后有现成的 DOMContentLoaded 事件。对于Safari 浏览器,有document.onreadystatechange事件,当该触发时,如果 document.readyState=complete时,可视为dom树已经载入。

对于ie,当在iframe内时,同样有document.onreadystatechange事件,对于ie在非iframe内时,只有不断地通过能否执行doScroll判断dom是否加载完毕。

在本例中每间隔5毫秒尝试去执行 document.documentElement.doScroll(‘left')。在ie8下,貌视非iframe窗口也会有 document.onreadystatechange事件,另外也可以在构建自己的框架时使用此函数。

(function(){
  var isReady=false; //判断onDOMReady方法是否已经被执行过
  var readyList= [];//把需要执行的方法先暂存在这个数组里
  var timer;//定时器句柄
 
  ready=function(fn)
  {
   if (isReady )
    fn.call( document);
   else
    readyList.push( function() { return fn.call(this);});
   return this;
  }
 
  var onDOMReady=function(){
   for(var i=0;i< readyList.length;i++)
   {
    readyList[i].apply(document);
   }
   readyList = null;
  }
 
  var bindReady = function(evt)
  {
   if(isReady) return;
   isReady=true;
   onDOMReady.call(window);
   if(document.removeEventListener)
   {
    document.removeEventListener("DOMContentLoaded", bindReady, false);
   }
   else if(document.attachEvent)
   {
    document.detachEvent("onreadystatechange", bindReady);
    if(window == window.top){
     clearInterval(timer);//事件发生后清除定时器
     timer = null;
    }
   }
  };
 
  if(document.addEventListener){
   document.addEventListener("DOMContentLoaded", bindReady, false);
  }
  else if(document.attachEvent)//非最顶级父窗口
 
  {
   document.attachEvent("onreadystatechange", function(){
    if((/loaded|complete/).test(document.readyState))
    bindReady();
   });
 
  if(window == window.top)//在应用有frameset或者iframe的页面时,parent是父窗口,top是最顶级父窗口(有的窗口中套了好几层frameset或者iframe)
  {
   timer = setInterval(function(){
    try
    {
     isReady||document.documentElement.doScroll('left');//在IE下用能否执行doScroll判断 dom是否加载完毕
    }
    catch(e)
    {
     return;
    }
    bindReady();
   },5);
  }
  }
 })();

下面是使用方法:

ready(dosomething);//dosomething为已存在的函数
 //也可以通过闭包来使用
 ready(function(){
  //这里是逻辑代码
 });

以上这篇原生JS实现DOM加载完成马上执行JS代码的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 面向对象,实现namespace,class,继承,重载
Oct 29 Javascript
javascript中的undefined 与 null 的区别  补充篇
Mar 17 Javascript
jquery中添加属性和删除属性
Jun 03 Javascript
js实现固定显示区域内自动缩放图片的方法
Jul 18 Javascript
jQuery-1.9.1源码分析系列(十)事件系统之事件体系结构
Nov 19 Javascript
浏览器环境下JavaScript脚本加载与执行探析之defer与async特性
Jan 14 Javascript
JS获取IMG图片高宽的简单实例
May 17 Javascript
有关suggest快速删除后仍然出现下拉列表的bug问题
Dec 02 Javascript
JavaScript+HTML5实现的日期比较功能示例
Jul 12 Javascript
vuex根据不同的用户权限展示不同的路由列表功能
Sep 20 Javascript
weui中的picker使用js进行动态绑定数据问题
Nov 06 Javascript
vue组件中实现嵌套子组件案例
Aug 31 Javascript
vue加载完成后的回调函数方法
Sep 07 #Javascript
使用vue-router与v-if实现tab切换遇到的问题及解决方法
Sep 07 #Javascript
VUE DOM加载后执行自定义事件的方法
Sep 07 #Javascript
详解JavaScript事件循环机制
Sep 07 #Javascript
解决vue 引入子组件报错的问题
Sep 06 #Javascript
解决vue v-for 遍历循环时key值报错的问题
Sep 06 #Javascript
vue 解决循环引用组件报错的问题
Sep 06 #Javascript
You might like
php模拟socket一次连接,多次发送数据的实现代码
2011/07/26 PHP
提高PHP编程效率的方法
2013/11/07 PHP
php根据数据id自动生成编号的实现方法
2016/10/16 PHP
理解JavaScript的caller,callee,call,apply
2009/04/28 Javascript
基于jquery的图片幻灯展示源码
2012/07/15 Javascript
JS文本框追加多个下拉框的值的简单实例
2013/07/12 Javascript
当滚动条滚动到页面底部自动加载增加内容的js代码
2014/05/13 Javascript
jquery插件推荐 jquery.cookie
2014/11/09 Javascript
详解JavaScript函数
2015/12/01 Javascript
高效的jquery数字滚动特效
2015/12/17 Javascript
angularjs在ng-repeat中使用ng-model遇到的问题
2016/01/21 Javascript
详解Angular.js的$q.defer()服务异步处理
2016/11/06 Javascript
基于bootstrap-datetimepicker.js不支持IE8的快速解决方法
2016/11/07 Javascript
自定义事件解决重复请求BUG的问题
2017/07/11 Javascript
Angular中响应式表单的三种更新值方法详析
2017/08/22 Javascript
vue项目base64字符串转图片的实现代码
2018/07/13 Javascript
javascript将16进制的字符串转换为10进制整数hex
2020/03/05 Javascript
[55:32]2018DOTA2亚洲邀请赛 4.4 淘汰赛 EG vs LGD 第二场
2018/04/05 DOTA
LRUCache的实现原理及利用python实现的方法
2017/11/21 Python
Python计算开方、立方、圆周率,精确到小数点后任意位的方法
2018/07/17 Python
pycharm+PyQt5+python最新开发环境配置(踩坑)
2019/02/11 Python
python super函数使用方法详解
2020/02/14 Python
css3 仿写阿里云水纹效果的示例代码
2018/02/10 HTML / CSS
英国汽车座椅和婴儿车购物网站:Uber Kids
2017/04/19 全球购物
网络通讯中,端口有什么含义,端口的取值范围
2012/11/23 面试题
介绍一下Linux内核的排队自旋锁
2014/01/04 面试题
讲文明树新风公益广告宣传方案
2014/02/25 职场文书
《独坐敬亭山》教学反思
2014/04/08 职场文书
安全月宣传标语
2014/10/07 职场文书
赵乐秦在党的群众路线教育实践活动总结大会上的讲话稿
2014/10/25 职场文书
2014年党的群众路线学习心得体会
2014/11/05 职场文书
努力学习保证书
2015/02/26 职场文书
收入证明申请书
2015/06/12 职场文书
vue项目支付功能代码详解
2022/02/18 Vue.js
简单聊聊Golang中defer预计算参数
2022/03/25 Golang
Java GUI编程菜单组件实例详解
2022/04/07 Java/Android