原生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中split() 使用方法汇总
Apr 17 Javascript
jQuery实现带动画效果的多级下拉菜单代码
Sep 08 Javascript
使用jQuery的easydrag插件实现可拖动的DIV弹出框
Feb 19 Javascript
js获取iframe中的window对象的实现方法
May 20 Javascript
bootstrap模态框消失问题的解决方法
Dec 02 Javascript
详解Vue + Vuex 如何使用 vm.$nextTick
Nov 20 Javascript
javascript按顺序加载运行js方法
Dec 01 Javascript
基于js 各种排序方法和sort方法的区别(详解)
Jan 03 Javascript
js Element Traversal规范中的元素遍历方法
Apr 19 Javascript
AngularJS 监听变量变化的实现方法
Oct 09 Javascript
微信小程序 button样式设置为图片的方法
Jun 19 Javascript
vue中的循环对象属性和属性值用法
Sep 04 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
重量级动漫纷纷停播!唯独OVERLORD第四季正在英魂之刃继续更新
2020/05/06 日漫
如何使用PHP中的字符串函数
2006/11/24 PHP
js 多浏览器分别判断代码
2010/04/01 Javascript
js判断IE浏览器版本过低示例代码
2013/11/22 Javascript
jquery基础教程之deferred对象使用方法
2014/01/22 Javascript
jquery easyui 对于开始时间小于结束时间的判断示例
2014/03/22 Javascript
jQuery选择器源码解读(三):tokenize方法
2015/03/31 Javascript
Bootstrap每天必学之表格
2015/11/23 Javascript
JavaScript添加随滚动条滚动窗体的方法
2016/02/23 Javascript
仿百度换肤功能的简单实例代码
2016/07/11 Javascript
JS中的数组方法笔记整理
2016/07/26 Javascript
Jquery调用iframe父页面中的元素及方法
2016/08/23 Javascript
AngularJS实现给动态生成的元素绑定事件的方法
2016/12/14 Javascript
JS正则RegExp.test()使用注意事项(不具有重复性)
2016/12/28 Javascript
js+html5生成自动排列对话框实例
2017/10/09 Javascript
如何手动实现es5中的bind方法详解
2018/12/07 Javascript
微信小程序实现收货地址左滑删除
2020/11/18 Javascript
Vue的编码技巧与规范使用详解
2019/08/28 Javascript
vue中的mescroll搜索运用及各种填坑处理
2019/10/30 Javascript
在Vue中使用CSS3实现内容无缝滚动的示例代码
2020/11/27 Vue.js
vue3使用vue-count-to组件的实现
2020/12/25 Vue.js
vue3自定义dialog、modal组件的方法
2021/01/04 Vue.js
[46:58]完美世界DOTA2联赛PWL S3 Forest vs LBZS 第一场 12.17
2020/12/19 DOTA
python中自带的三个装饰器的实现
2019/11/08 Python
Python grequests模块使用场景及代码实例
2020/08/10 Python
Django CBV模型源码运行流程详解
2020/08/17 Python
美国宠物商店:Wag.com
2016/10/25 全球购物
JoJo Maman Bébé爱尔兰官网:英国最受欢迎的精品母婴品牌
2020/12/20 全球购物
几道PHP面试题
2013/04/14 面试题
Final类有什么特点
2012/04/25 面试题
派出所正风肃纪剖析材料
2014/10/10 职场文书
Nginx URL重写rewrite机制原理及使用实例
2021/04/01 Servers
【HBU】数据库第四周 单表查询
2021/04/05 SQL Server
Ajax 的初步实现(使用vscode+node.js+express框架)
2021/06/18 Javascript
Oracle表空间与权限的深入讲解
2021/11/17 Oracle
错误码NET::ERR_CERT_DATE_INVALID证书已过期解决方法?
2022/07/07 数码科技