javascript 模拟JQuery的Ready方法实现并出现的问题


Posted in Javascript onDecember 06, 2009

dom加载完后执行,一直不了解,基于对网上的一些方法逻辑不了解,所以去看了《jquery源代码研究(ready函数) 》这篇文章后自己写入如下代码(已有详细说明)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 
<title>document.ready</title> 
<script type="text/javascript" src="js/jquery-1.3.2.js"></script> 
<script type="text/javascript"> 
var Darren; 
(function(){ 
var isReady=false; //是否已经加载完毕 
var readBound=false; //判断是否已经调用过循环事件 
var readylist=[]; //把需要执行的方法先暂存在这个数组里 
//判断浏览器,该方法来自Cloudgamer JavaScript Library v0.1 
var Browser = (function(ua){ 
var b = { 
msie: /msie/.test(ua) && !/opera/.test(ua), 
opera: /opera/.test(ua), 
safari: /webkit/.test(ua) && !/chrome/.test(ua), 
firefox: /firefox/.test(ua), 
chrome: /chrome/.test(ua) 
}; 
var vMark = ""; 
for (var i in b) { 
if (b[i]) { 
vMark = i; 
} 
} 
if (b.safari) { 
vMark = "version"; 
} 
b.version = RegExp("(?:" + vMark + ")[\\/: ]([\\d.]+)").test(ua) ? RegExp.$1 : "0"; 
b.ie = b.msie; 
b.ie6 = b.msie && parseInt(b.version) == 6; 
b.ie7 = b.msie && parseInt(b.version) == 7; 
b.ie8 = b.msie && parseInt(b.version) == 8; 
return b; 
})(window.navigator.userAgent.toLowerCase()); 
function bindReady() 
{ 
if(readBound){ //保证bindReady方法只执行一遍 
return; 
} 
readBound=true; 
//For IE并且不是嵌套在frame中 
if (Browser.msie && window==top) 
{ 
(function(){ 
if (isReady) { 
return; 
} 
try { 
document.documentElement.doScroll("left"); //如果没加载dom完毕这个会报错 
} 
catch (error) { 
setTimeout(arguments.callee, 0); //循环调用父函数,也就是ready方法 
return; 
} 
Test.Done(); 
})(); 
}else if(Browser.firefox)//For FF 
{ 
document.addEventListener( "DOMContentLoaded", Test.Done, false ); 
} 
} 
var Test={ 
ready:function(fn){ 
bindReady();//判断是否加载完毕 
if(isReady) 
{ 
fn.call(document); //加载完毕,直接调用 
}else{ 
readylist.push(fn);//如果还没加载完成则将该方法暂存到readylist数组中,以便以后调用 
} 
return this; 
} 
}; 
//静态方法:加载完毕执行 
Test.Done=function(){ 
if (!isReady) { 
isReady=true; 
} 
readylist[0].call(document); 
} 
Darren=Test; 
})(); 
//测试 
Darren.ready(function(){ 
alert("my"); 
document.getElementById("test").innerHTML="haha" //成功读取dom 
}); 
$(function(){alert("jq")}); 
window.onload=function(){alert("default")} 
</script> 
</head> 
<body> 
<div id="test">test</div> 
</body> 
</html>

由于要和jq做对比,所以测试时候需要导入jq库。函数本身是没有调用jq的,请放心引用。

代码我通过封装完成,直接Darren.ready(fn)就可执行。

后来通过测试还是出现一个奇怪的问题:在FF下的执行顺序是jq -> my -> load 。也就是说我这个函数能够在onload事件执行前触发,但会晚于jq的ready。对这个还是比较满意。

但是在IE下测试居然是:jq -> load -> my。也就是 我的这个函数虽然能够把代码提前,但是还是在onload事件执行后触发的,百思不得其解。

完同志们解答下如何实现onload之前执行,jq又是怎么实现的,我完全模拟jq的结构,但是还是不能达到目的,难道中间有漏?

另大家可以参考下面的代码

var ready=function(readyCall) { 
if(document.addEventListener) 
document.addEventListener("DOMContentLoaded",function() { 
document.removeEventListener("DOMContentLoaded",arguments.callee,false); 
readyCall(); 
},false); 
else if(document.attachEvent) {//for IE 
if(document.documentElement.doScroll && window.self==window.top) { 
(function() { 
try { 
document.documentElement.doScroll("left"); 
}catch(ex) { 
setTimeout(arguments.callee,5); 
return; 
} 
readyCall(); 
})(); 
}else {//maybe late but also for iframes 
document.attachEvent("onreadystatechange",function() { 
if(document.readyState==="complete") { 
document.detachEvent("onreadystatechange", arguments.callee); 
readyCall(); 
} 
}); 
} 
} 
}
Javascript 相关文章推荐
JavaScript 学习笔记(七)字符串的连接
Dec 31 Javascript
c#+jquery实现获取radio和checkbox的值
Sep 12 Javascript
浅谈JavaScript Date日期和时间对象
Dec 29 Javascript
jquery实现通用的内容渐显Tab选项卡效果
Sep 07 Javascript
深入探讨前端框架react
Dec 09 Javascript
最佳的JavaScript错误处理实践
Jul 16 Javascript
JavaScript 总结几个提高性能知识点(推荐)
Feb 20 Javascript
jQuery实现表格奇偶行显示不同背景色 就这么简单
Mar 13 Javascript
JavaScript实现实时更新系统时间的实例代码
Apr 04 Javascript
JavaScript 中调用 Kotlin 方法实例详解
Jun 09 Javascript
详解基于Angular4+ server render(服务端渲染)开发教程
Aug 28 Javascript
封装微信小程序http拦截器过程解析
Aug 13 Javascript
javascript 动态生成私有变量访问器
Dec 06 #Javascript
JavaScript 加号(+)运算符号
Dec 06 #Javascript
javascript Demo模态窗口
Dec 06 #Javascript
jquery select操作的日期联动实现代码
Dec 06 #Javascript
JSON 编辑器实现代码
Dec 06 #Javascript
JS 控制非法字符的输入代码
Dec 04 #Javascript
对采用动态原型方式无法展示继承机制得思考
Dec 04 #Javascript
You might like
php实现无限级分类实现代码(递归方法)
2011/01/01 PHP
php设计模式 State (状态模式)
2011/06/26 PHP
php输出echo、print、print_r、printf、sprintf、var_dump的区别比较
2013/06/21 PHP
php实例分享之mysql数据备份
2014/05/19 PHP
PHP实现微信图片上传到服务器的方法示例
2017/06/29 PHP
javascript XML数据显示为HTML一例
2008/12/23 Javascript
javascript 面向对象 function类
2010/05/13 Javascript
JS 修改URL参数(实现代码)
2013/07/08 Javascript
Jquery 数组操作大全个人总结
2013/11/13 Javascript
node.js中的fs.readdirSync方法使用说明
2014/12/17 Javascript
JavaScript获得指定对象大小的方法
2015/07/01 Javascript
JavaScript中数组去除重复的三种方法
2016/04/22 Javascript
onclick和onblur冲突问题的快速解决方法
2016/04/28 Javascript
js简单倒计时实现代码
2016/04/30 Javascript
jquery+ajax+text文本框实现智能提示完整实例
2016/07/09 Javascript
微信小程序 加载 app-service.js 错误解决方法
2016/10/12 Javascript
微信小程序开发之视频播放器 Video 弹幕 弹幕颜色自定义实例
2016/12/08 Javascript
Javascript中的prototype与继承
2017/02/06 Javascript
Bootstrap modal 多弹窗之叠加显示不出弹窗问题的解决方案
2017/02/23 Javascript
Node.js中Bootstrap-table的两种分页的实现方法
2017/09/18 Javascript
node实现的爬虫功能示例
2018/05/04 Javascript
详解JS实现系统登录页的登录和验证
2019/04/29 Javascript
Vue+Typescript中在Vue上挂载axios使用时报错问题
2019/08/07 Javascript
JavaScript使用canvas绘制随机验证码
2020/02/17 Javascript
在Apache服务器上同时运行多个Django程序的方法
2015/07/22 Python
python编程嵌套函数实例代码
2018/02/11 Python
通过字符串导入 Python 模块的方法详解
2019/10/27 Python
Python3 解决读取中文文件txt编码的问题
2019/12/20 Python
python软件测试Jmeter性能测试JDBC Request(结合数据库)的使用详解
2021/01/26 Python
突袭HTML5之Javascript API扩展5—其他扩展(应用缓存/服务端消息/桌面通知)
2013/01/31 HTML / CSS
如何用H5实现一个触屏版的轮播器的实例
2017/01/09 HTML / CSS
顺丰快递Java软件工程师面试题
2015/07/31 面试题
技校生自我鉴定范文
2013/09/26 职场文书
英文版餐饮业求职信
2013/10/18 职场文书
《叶问2》观后感
2015/06/15 职场文书
Promise静态四兄弟实现示例详解
2022/07/07 Javascript