原生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 相关文章推荐
JS OOP包机制,类创建的方法定义
Nov 02 Javascript
Javascript 浮点运算的问题分析与解决方法
Aug 27 Javascript
Jquery对数组的操作技巧整理
Mar 25 Javascript
a标签click和href执行顺序探讨
Jun 23 Javascript
浅谈Node.js中的定时器
Jun 18 Javascript
Bootstrap每天必学之标签与徽章
Nov 27 Javascript
浅谈Javascript中的函数、this以及原型
Oct 09 Javascript
Windows下Node.js安装及环境配置方法
Sep 18 Javascript
Vue递归组件+Vuex开发树形组件Tree--递归组件的简单实现
Apr 01 Javascript
简单了解微信小程序 e.target与e.currentTarget的不同
Sep 27 Javascript
多页vue应用的单页面打包方法(内含打包模式的应用)
Jun 11 Javascript
一分钟学会JavaScript中的try-catch
Dec 14 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/03/02 日漫
php中的MVC模式运用技巧
2007/05/03 PHP
php实现屏蔽掉黑帽SEO的搜索关键字
2015/04/15 PHP
php实现根据身份证获取精准年龄
2020/02/26 PHP
用javascript实现自定义标签
2007/05/08 Javascript
GRID拖拽行的实例代码
2013/07/18 Javascript
一个JS的日期格式化算法示例
2013/07/31 Javascript
Jquery中Event对象属性小结
2015/02/27 Javascript
jQuery文件上传控件 Uploadify 详解
2016/06/20 Javascript
web前端开发upload上传头像js示例代码
2016/10/22 Javascript
微信小程序--onShareAppMessage分享参数用处(页面分享)
2017/04/18 Javascript
bootstrap treeview 扩展addNode方法动态添加子节点的方法
2017/11/21 Javascript
Angular2.0/4.0 使用Echarts图表的示例代码
2017/12/07 Javascript
vue interceptor 使用教程实例详解
2018/09/13 Javascript
浅谈javascript错误处理
2019/08/11 Javascript
Angular6项目打包优化的实现方法
2019/12/15 Javascript
解决pycharm双击但是无法打开的情况
2020/10/31 Javascript
[00:43]2016完美“圣”典风云人物:单车宣传片
2016/12/02 DOTA
[01:03:51]2018DOTA2亚洲邀请赛 4.7 淘汰赛 VP vs LGD 第三场
2018/04/09 DOTA
详解Python中的多线程编程
2015/04/09 Python
Python检测一个对象是否为字符串类的方法
2015/05/21 Python
Python给定一个句子倒序输出单词以及字母的方法
2018/12/20 Python
python使用thrift教程的方法示例
2019/03/21 Python
python 使用pdfminer3k 读取PDF文档的例子
2019/08/27 Python
Python基本语法之运算符功能与用法详解
2019/10/22 Python
django连接mysql数据库及建表操作实例详解
2019/12/10 Python
简单了解Python读取大文件代码实例
2019/12/18 Python
python pandas利用fillna方法实现部分自动填充功能
2020/03/16 Python
python高级特性简介
2020/08/13 Python
利用CSS的Sass预处理器(框架)来制作居中效果
2016/03/10 HTML / CSS
Zipadee-Zip襁褓过渡毯:Sleeping Baby
2018/12/30 全球购物
同学会邀请书大全
2014/01/12 职场文书
银行内勤岗位职责
2014/04/09 职场文书
体育部部长竞选稿
2015/11/21 职场文书
python模块与C和C++动态库相互调用实现过程示例
2021/11/02 Python
Nginx下SSL证书安装部署步骤介绍
2021/12/06 Servers