原生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 解析url的search方法
Feb 09 Javascript
formValidator3.3的ajaxValidator一些异常分析
Jul 12 Javascript
js获取html参数及向swf传递参数应用介绍
Feb 18 Javascript
JS如何将UTC格式时间转本地格式
Sep 04 Javascript
使用AngularJS来实现HTML页面嵌套的方法
Jun 17 Javascript
通过AngularJS实现图片上传及缩略图展示示例
Jan 03 Javascript
Vue2单一事件管理组件通信
May 09 Javascript
JavaScript 程序错误Cannot use 'in' operator to search的解决方法
Jul 10 Javascript
JS如何实现在页面上快速定位(锚点跳转问题)
Aug 14 Javascript
vue中子组件的methods中获取到props中的值方法
Aug 27 Javascript
JavaScript设计模式之装饰者模式实例详解
Jan 17 Javascript
详解实现一个通用的“划词高亮”在线笔记功能
Apr 23 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无限分类的类
2007/01/02 PHP
PHP中的MYSQL常用函数(php下操作数据库必备)
2010/09/12 PHP
常见的PHP五种设计模式小结
2011/03/23 PHP
PHP对象转换为数组函数(递归方法)
2012/02/04 PHP
详解yii2使用多个数据库的案例
2017/06/16 PHP
PHP时间日期增减操作示例【date strtotime实现加一天、加一月等操作】
2018/12/21 PHP
基于jQuery的的一个隔行变色,鼠标移动变色的小插件
2010/07/06 Javascript
js post提交调用方法
2014/02/12 Javascript
通过隐藏iframe实现文件下载的js方法介绍
2014/02/26 Javascript
JavaScript跨浏览器获取页面中相同class节点的方法
2015/03/03 Javascript
JavaScript移除数组内重复元素的方法
2015/03/18 Javascript
SpringMVC restful 注解之@RequestBody进行json与object转换
2015/12/10 Javascript
jQuery插件实现文字无缝向上滚动效果代码
2016/02/25 Javascript
浅谈javascript中执行环境(作用域)与作用域链
2016/12/08 Javascript
教大家轻松制作Bootstrap漂亮表格(table)
2016/12/13 Javascript
AngularJS中下拉框的高级用法示例
2017/10/11 Javascript
浅谈AngularJs 双向绑定原理(数据绑定机制)
2017/12/07 Javascript
详解vue中axios的封装
2018/07/18 Javascript
AngularJS发送异步Get/Post请求方法
2018/08/13 Javascript
LayUI动态设置checkbox不显示的解决方法
2019/09/02 Javascript
写给新手同学的vuex快速上手指北小结
2020/04/14 Javascript
Python判断操作系统类型代码分享
2014/11/22 Python
Python解析xml中dom元素的方法
2015/03/12 Python
对pandas中Series的map函数详解
2018/07/25 Python
python版本五子棋的实现代码
2018/12/11 Python
python挖矿算力测试程序详解
2019/07/03 Python
python正则表达式匹配不包含某几个字符的字符串方法
2019/07/23 Python
Django实现文件上传下载
2019/10/06 Python
pip安装提示Twisted错误问题(Python3.6.4安装Twisted错误)
2020/05/09 Python
使用css3实现的windows8开机加载动画
2014/12/09 HTML / CSS
css3实现可拖动的魔方3d效果
2019/05/07 HTML / CSS
美国室内和室外装饰花盆购物网站:ePlanters
2019/03/22 全球购物
党在我心中演讲稿
2014/09/02 职场文书
滴水洞导游词
2015/02/10 职场文书
车间统计员岗位职责
2015/04/14 职场文书
环保守法证明
2015/06/24 职场文书