原生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针对DOM的应用分析(三)
Apr 15 Javascript
13 个JavaScript 性能提升技巧分享
Jul 26 Javascript
js Dialog 去掉右上角的X关闭功能
Apr 23 Javascript
JS简单编号生成器实现方法(附demo源码下载)
Apr 05 Javascript
js无提示关闭浏览器窗口的两种方法分析
Nov 06 Javascript
JavaScript无阻塞加载和defer、async详解
Feb 26 Javascript
Node.js微信 access_token ( jsapi_ticket ) 存取与刷新的示例
Sep 30 Javascript
javascrit中undefined和null的区别详解
Apr 07 Javascript
基于layui table返回的值的多级嵌套的解决方法
Sep 19 Javascript
如何编写一个 Webpack Loader的实现
Oct 18 Javascript
vue-cli —— 如何局部修改Element样式
Oct 22 Javascript
原生js实现弹窗消息动画
Nov 20 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 分页类 扩展代码
2009/06/11 PHP
PHP自动识别字符集并完成转码详解
2013/08/02 PHP
php数组函数array_key_exists()小结
2015/12/10 PHP
浅谈PHP中try{}catch{}的使用方法
2016/12/09 PHP
Yii2表单事件之Ajax提交实现方法
2017/05/04 PHP
ThinkPHP 3.2.3实现页面静态化功能的方法详解
2017/08/03 PHP
在一个form用一个SUBMIT(或button)分别提交到两个处理表单页面的代码
2007/02/15 Javascript
JavaScript Undefined,Null类型和NaN值区别
2008/10/22 Javascript
深入理解JavaScript系列(7) S.O.L.I.D五大原则之开闭原则OCP
2012/01/15 Javascript
jQuery表格插件datatables用法总结
2014/09/05 Javascript
浅谈javascript的调试
2015/01/28 Javascript
修改js confirm alert 提示框文字的简单实例
2016/06/10 Javascript
js表单登陆验证示例
2016/10/19 Javascript
Vue.js 单页面多路由区域操作的实例详解
2017/07/17 Javascript
vuejs使用$emit和$on进行组件之间的传值的示例
2017/10/04 Javascript
vue 挂载路由到头部导航的方法
2017/11/13 Javascript
AngularJS双向数据绑定原理之$watch、$apply和$digest的应用
2018/01/30 Javascript
centos 上快速搭建ghost博客方法分享
2018/05/23 Javascript
详解js中let与var声明变量的区别
2020/04/05 Javascript
浅谈laytpl 模板空值显示null的解决方法及简单的js表达式
2019/09/19 Javascript
使用 Angular RouteReuseStrategy 缓存(路由)组件的实例代码
2019/11/01 Javascript
Python使用文件锁实现进程间同步功能【基于fcntl模块】
2017/10/16 Python
python实现最长公共子序列
2018/05/22 Python
机器学习之KNN算法原理及Python实现方法详解
2018/07/09 Python
设置python3为默认python的方法
2018/10/31 Python
Python实现的序列化和反序列化二叉树算法示例
2019/03/02 Python
Python自定义函数计算给定日期是该年第几天的方法示例
2019/05/30 Python
使用Python OpenCV为CNN增加图像样本的实现
2019/06/10 Python
selenium+PhantomJS爬取豆瓣读书
2019/08/26 Python
python-图片流传输的思路及示例(url转换二维码)
2020/12/21 Python
HTML5 device access 设备访问详解
2018/05/24 HTML / CSS
2014年标准化工作总结
2014/12/17 职场文书
售后服务质量承诺书
2015/04/29 职场文书
大学生安全教育心得体会
2016/01/15 职场文书
浅谈Redis主从复制以及主从复制原理
2021/05/29 Redis
Python将CSV文件转化为HTML文件的操作方法
2021/06/30 Python