用纯原生js实现jquery的ready函数(两种实现)
第一种实现方式:
var dom = new function() {
  var dom = [];
  dom.isReady = false;
  dom.isFunction = function(obj) {
    return Object.prototype.toString.call(obj) === "[object Function]";
  }
  //先会执行下面的分支函数,然后执行dom.initReady()函数,因为要等到DOM建完后才会执行
  dom.Ready = function(fn) {
    dom.initReady();//如果没有建成DOM树,则走第二步,存储起来一起杀
    if(dom.isFunction(fn)) {
      if(dom.isReady) {
        fn();//如果已经建成DOM,则来一个杀一个
      } else {
        dom.push(fn);//存储加载事件
      }
    }
  }
  dom.fireReady = function() {
    if (dom.isReady)  return;
    dom.isReady = true;
    for(var i=0, n=dom.length; i<n; i++) {
      dom[i]();
    }
    dom.length = 0;//清空事件
  }
  dom.initReady = function() {
    if (document.addEventListener) {
      document.addEventListener( "DOMContentLoaded", function() {
        document.removeEventListener( "DOMContentLoaded", arguments.callee, false );//清除加载函数
        dom.fireReady();
      }, false );
    } else {
      if (document.getElementById) {
        document.write("<script id=\"ie-domReady\" defer='defer'src=\"//:\"><\/script>");
        document.getElementById("ie-domReady").onreadystatechange = function() {
          if (this.readyState === "complete") {
            dom.fireReady();
            this.onreadystatechange = null;
            this.parentNode.removeChild(this)
          }
        };
      }
    }
  }
  return dom;
}
第二种实现方式
//浏览器检测
(function () {
window.sys = {};
var ua = navigator.userAgent.toLowerCase();
var s;
(s = ua.match(/msie ([\d.]+)/)) ? sys.ie = s[1] :
(s = ua.match(/firefox\/([\d.]+)/)) ? sys.firefox = s[1] :
(s = ua.match(/chrome\/([\d.]+)/)) ? sys.chrome = s[1] :
(s = ua.match(/opera\/.*version\/([\d.]+)/)) ? sys.opera = s[1] :
(s = ua.match(/version\/([\d.]+).*safari/)) ? sys.safari = s[1] : 0; if (/webkit/.test(ua)) sys.webkit = ua.match(/webkit\/([\d.]+)/)[1];
})(); //DOM加载
function Ready(fn) {
var isReady = false;
var timer = null;
function doReady() {
if (timer) clearInterval(timer);
if (isReady) return;
isReady = true;
fn();
} if ((sys.opera && sys.opera < 9) || (sys.firefox && sys.firefox < 3) || (sys.webkit && sys.webkit < 525)) {
timer = setInterval(function () {
if (document && document.getElementById && document.getElementsByTagName && document.body) {
doReady();
}
}, 1);
} else if (document.addEventListener) {//W3C
addEvent(document, 'DOMContentLoaded', function () {
fn();
removeEvent(document, 'DOMContentLoaded', arguments.callee);
});
} else if (sys.ie && sys.ie < 9){
var timer = null;
timer = setInterval(function () {
try {
document.documentElement.doScroll('left');
doReady();
} catch (e) {};
}, 1);
}
}
当然上面的Ready函数需要依赖addEvent和removeEvent函数,这两个函数是经过兼容处理的函数,兼容所有浏览器,无任何bug,代码:
//跨浏览器添加事件绑定
function addEvent(obj, type, fn) {
if (typeof obj.addEventListener != 'undefined') {
obj.addEventListener(type, fn, false);
} else {
//创建一个存放事件的哈希表(散列表)
if (!obj.events) obj.events = {};
//第一次执行时执行
if (!obj.events[type]) {
//创建一个存放事件处理函数的数组
obj.events[type] = [];
//把第一次的事件处理函数先储存到第一个位置上
if (obj['on' + type]) obj.events[type][0] = fn;
} else {
//同一个注册函数进行屏蔽,不添加到计数器中
if (addEvent.equal(obj.events[type], fn)) return false;
}
//从第二次开始我们用事件计数器来存储
obj.events[type][addEvent.ID++] = fn;
//执行事件处理函数
obj['on' + type] = addEvent.exec;
}
} //为每个事件分配一个计数器
addEvent.ID = 1; //执行事件处理函数
addEvent.exec = function (event) {
var e = event || addEvent.fixEvent(window.event);
var es = this.events[e.type];
for (var i in es) {
es[i].call(this, e);
}
}; //同一个注册函数进行屏蔽
addEvent.equal = function (es, fn) {
for (var i in es) {
if (es[i] == fn) return true;
}
return false;
} //把IE常用的Event对象配对到W3C中去
addEvent.fixEvent = function (event) {
event.preventDefault = addEvent.fixEvent.preventDefault;
event.stopPropagation = addEvent.fixEvent.stopPropagation;
event.target = event.srcElement;
return event;
}; //IE阻止默认行为
addEvent.fixEvent.preventDefault = function () {
this.returnValue = false;
}; //IE取消冒泡
addEvent.fixEvent.stopPropagation = function () {
this.cancelBubble = true;
}; //跨浏览器删除事件
function removeEvent(obj, type, fn) {
if (typeof obj.removeEventListener != 'undefined') {
obj.removeEventListener(type, fn, false);
} else {
if (obj.events) {
for (var i in obj.events[type]) {
if (obj.events[type][i] == fn) {
delete obj.events[type][i];
}
}
}
}
}
用纯原生js实现jquery的ready函数(两种实现)的更多相关文章
- 【JS】怎样用原生JS实现jQuery的ready方法
		Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,只是与window.onload方法还是有差别的. 总的来说,window. ... 
- 原生JS—实现图片循环切换的两种方法
		今天我们主要讲讲如何使用原生JS实现图片的循环切换的方法.多余的话我们就不多说了,我们一个一个开始讲吧. 1 原生JS实现图片循环切换 -- 方法一 在上栗子之前我们先简单介绍一下所用的一些知识点. ... 
- 原生JS实现jquery的ready
		function ready(fn){ if(document.addEventListener){ //标准浏览器 document.addEventListener('DOMContentLoad ... 
- onload事件与ready事件的区别,原生js与jquery的区别
		onload事件与ready事件分别是原生js与jquery的入口函数 原生js入口函数写法: window.onload=function(){ } jquery入口函数写法: $(document ... 
- 原生JS和JQuery的区别
		1.原生js和jQuery的入口函数加载模式不同 原生js等页面dom加载完成并且图片等资源也加载完成之后才会执行: jQuery则是等页面dom加载完成执行,不会等图片等资源也加载完成: (也就是说 ... 
- 【前端性能】必须要掌握的原生JS实现JQuery
		很多时候,我们经常听见有人说jquery有多快多快.在这个各种类库满天飞的时候,不得不说的是,能有原生JS快吗? 是的,明显原生JS要更快,因为诸如JQuery这样的库必须要兼容各种浏览器和低版本和许 ... 
- 移动端lCalendar纯原生js日期时间选择器
		网上找过很多的移动端基于zepto或jquery的日期选择器,在实际产品中也用过一两种,觉得都不太尽如人意,后来果断选择了H5自己的日期input表单,觉得还可以,至少不用引用第三方插件了,性能也不错 ... 
- 纯原生js移动端图片压缩上传插件
		前段时间,同事又来咨询一个问题了,说手机端动不动拍照就好几M高清大图,上传服务器太慢,问问我有没有可以压缩图片并上传的js插件,当然手头上没有,别慌,我去网上搜一搜. 结果呢,呵呵...诶~又全是基于 ... 
- 原生js替换jQuery各种方法-中文版
		原文https://github.com/nefe/You-D... 原生JS与jQuery操作DOM对比 You Don't Need jQuery 前端发展很快,现代浏览器原生 API 已经足够好 ... 
随机推荐
- jQuery.smoove — jQuery和CSS3炫酷滚动页面内容元素动画特效插件
			插件介绍: jQuery-smoove是一款jQuery和CSS3炫酷滚动页面内容元素动画特效插件.该内容元素动画插件在页面滚动到指定位置时,该位置的HTML元素会执行指定的CSS3动画特效,如旋转. ... 
- Core Data 概述
			Core Data是一个模型层的技术.Core Data帮助你建立代表程序状态的模型层.Core Data也是一种持久化技术,它能将模型对象的状态持久化到磁盘,但它最重要的特点是:Core Data不 ... 
- WiFi QC 自动测试:Qt控制无线路由器
			在测试wifi的时候,测试人员一般要使用很多不同型号的AP,并且需要不断地切换Chariot的配置. 这里的思路是致力于提供一个友好的GUI界面来自动控制AP,并且自动控制Chariot进行Throu ... 
- 云计算之路-阿里云上:Wireshark抓包分析一个耗时20秒的请求
			这篇博文分享的是我们针对一个耗时20秒的请求,用Wireshark进行抓包分析的过程. 请求的流程是这样的:客户端浏览器 -> SLB(负载均衡) -> ECS(云服务器) -> S ... 
- 正确对待bug
			正确对待bug 2016-10-09 公众号:一只程序媛 以前我一直以为bug是代码的天敌,我以为好的程序媛写出来的代码是应该没有bug的,零bug是终极奋斗目标. 后来,看到一句话"上帝创 ... 
- UITextField实现左侧空出一定的边距
			就是通过uitextfield的leftview来实现的,同时要设置leftviewmode. 如果设置左右边距,需要再加上rightView功能 -(void)setTextFieldLeftPad ... 
- SequoiaDB 系列之三   :SequoiaDB的高级功能
			上一篇简单描述了一下SequoiaDB的简单CRUD操作,本篇将讲述一下稍微高级点的功能. 部署在我机器上的集群环境,在经过创建名字为"foo"的cs,创建名字为"bar ... 
- 编写高质量代码改善C#程序的157个建议[为类型输出格式化字符串、实现浅拷贝和深拷贝、用dynamic来优化反射]
			前言 本文已更新至http://www.cnblogs.com/aehyok/p/3624579.html .本文主要学习记录以下内容: 建议13.为类型输出格式化字符串 建议14.正确实现浅拷贝和深 ... 
- (练习)rational rose进行用例图设计
			用例图: 
- java中的hashcode
			hashcode的作用 对于包含容器类型的程序设计语言来说,基本上都会涉及到hashCode.在Java中也一样,hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括 ... 
