用纯原生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 已经足够好 ...
随机推荐
- Linux第二次学习笔记
#Linux第二次实验(第三周) 学习目标 熟悉Linux系统下的开发环境 熟悉vi的基本操作 熟悉gcc编译器的基本原理 熟练使用gcc编译器的常用选项 熟练使用gdb调试技术 熟悉makefile ...
- 20145215实验三 敏捷开发与XP实践
20145215实验三 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验步骤 (一)敏捷开发与XP 软件工程是把系统的.有序的.可量化的方法应用到软件的开发.运营和维护上的过程.软 ...
- Javascript设计模式之我见:状态模式
大家好!本文介绍状态模式及其在Javascript中的应用. 模式介绍 定义 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 状态模式主要解决的是控制一个对象状态的条件表达式 ...
- 利用mstsc远程桌面传送文件,记录一下
尼玛之前服务器上传有点异常,在服务器装了一个上传下载监控的软件,用的是什么 绿色版QQ流量监控,绿色是挺绿色的,装了就等哭吧.没时间打字反正就是删除不了,后来想办法删除了.艹.所有服务除了系统服务能上 ...
- EF实体框架之CodeFirst二
在codefirst一中也说了Mapping是实体与数据库的纽带,model通过Mapping映射到数据库,我们可以从数据库的角度来分析?首先是映射到数据库,这个是必须的.数据库里面一般包括表.列.约 ...
- #Linux学习笔记# 自定义shell终端提示符
我使用的Linux发行版是LinuxMint 17.2 Rafaela,默认情况下Terminal中的shell提示包括了用户名.主机名.当前目录(绝对路径)和提示符.这样会导致当进入一个比较深的目录 ...
- .net截取两个字符串中间的内容
做模拟登录时,需要截取html代码中的名字,返回的字符串内容如下 <span class="welcome">您好<span style="font-s ...
- javascript继承(六)—实现多继承
在上一篇javascript继承—prototype最优两种继承(空函数和循环拷贝)(3) ,介绍了js较完美继承的两种实现方案,那么下面来探讨一下js里是否有多继承,如何实现多继承.在这里可以看看j ...
- Bata版本冲刺计划及安排
下一阶段需要改进完善的功能 UI: 1. 界面不够精细,布局不够美观并且尚有BUG没有解决,图形.色彩间不够协调. 2. 理清界面间的跳转逻辑. 搜索: 搜索成功并定位后,不会影响地理标签的显示. 定 ...
- iOS开发中的错误整理,(百思项目,指示器位置)设置控件尺寸和点坐标,先设置尺寸,再设置点坐标
之前对控件的尺寸和点的坐标的设置从来都是想到什么写什么,从来没有关心过顺序.然后就有了这次的血的教训!!!!! 下面是错误的截图,先设置的中心点,然后设置的宽度.程序运行就这样了,点别的没有毛病!!! ...