原生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 相关文章推荐
浅析tr的隐藏和显示问题
Mar 05 Javascript
js字符串日期yyyy-MM-dd转化为date示例代码
Mar 06 Javascript
元素未显示设置width/height时IE中使用currentStyle获取为auto
May 04 Javascript
Jquery焦点与失去焦点示例应用
Jun 10 Javascript
JS实现自动定时切换的简洁网页选项卡效果
Oct 13 Javascript
jQuery使用serialize()表单序列化时出现中文乱码问题的解决办法
Jul 27 Javascript
浅析vue数据绑定
Jan 17 Javascript
jQuery Validate 相关参数及常用的自定义验证规则
Mar 06 Javascript
JavaScript实现动态增删表格的方法
Mar 09 Javascript
vue的无缝滚动组件vue-seamless-scroll实例
Dec 18 Javascript
JavaScript学习笔记之基于定时器实现图片无缝滚动功能详解
Jan 09 Javascript
Vue实现星级评价效果实例详解
Dec 30 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
PHP5中的时间相差8小时的解决办法
2008/03/28 PHP
php获取qq用户昵称和在线状态(实例分析)
2013/10/27 PHP
php使用strtotime和date函数判断日期是否有效代码分享
2013/12/25 PHP
codeigniter显示所有脚本执行时间的方法
2015/03/21 PHP
PHP易混淆知识整理笔记
2015/09/24 PHP
PHP获取真实IP及IP模拟方法解析
2020/11/24 PHP
JCalendar 日历控件 v1.0 beta[兼容IE&amp;Firefox] 有文档和例子
2007/05/30 Javascript
javascript数字格式化通用类 accounting.js使用
2012/08/24 Javascript
jQuery插件cxSelect多级联动下拉菜单实例解析
2016/06/24 Javascript
JS使用onerror捕获异常示例
2016/08/03 Javascript
js放大镜放大购物图片效果
2017/01/18 Javascript
Vue.js实现输入框绑定的实例代码
2017/08/24 Javascript
angularjs路由传值$routeParams详解
2020/09/05 Javascript
bootstrap自定义样式之bootstrap实现侧边导航栏功能
2018/09/10 Javascript
jQuery鼠标滑过横向时间轴样式(代码详解)
2019/11/01 jQuery
JQuery获得内容和属性方法解析
2020/05/30 jQuery
vue组件讲解(is属性的用法)模板标签替换操作
2020/09/04 Javascript
举例讲解Python中装饰器的用法
2015/04/27 Python
Python中的super用法详解
2015/05/28 Python
python 删除大文件中的某一行(最有效率的方法)
2017/08/19 Python
python 定时器,轮询定时器的实例
2019/02/20 Python
python3.5安装python3-tk详解
2019/04/26 Python
详解python websocket获取实时数据的几种常见链接方式
2019/07/01 Python
Centos7下源码安装Python3 及shell 脚本自动安装Python3的教程
2020/03/07 Python
Python如何优雅删除字符列表空字符及None元素
2020/06/25 Python
HTML5新特性 多线程(Worker SharedWorker)
2017/04/24 HTML / CSS
BONIA官方网站:国际奢侈品牌和皮革专家
2016/11/27 全球购物
毕业生个人投资创业计划书
2014/01/04 职场文书
人事专员岗位说明书
2014/07/29 职场文书
优秀教研组申报材料
2014/12/26 职场文书
员工辞职信范文大全
2015/05/12 职场文书
企业宣传稿范文
2015/07/23 职场文书
《家》读后感:万惜拯救,冷暖自知
2019/09/25 职场文书
golang在GRPC中设置client的超时时间
2021/04/27 Golang
mysql timestamp比较查询遇到的坑及解决
2021/11/27 MySQL
MySQL RC事务隔离的实现
2022/03/31 MySQL