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 style 中visibility和display之间的区别
Jan 22 Javascript
javascript学习笔记(十二) RegExp类型介绍
Jun 20 Javascript
简单实用的反馈表单无刷新提交带验证
Nov 15 Javascript
第三篇Bootstrap网格基础
Jun 21 Javascript
封装获取dom元素的简单实例
Jul 08 Javascript
输入框点击时边框变色效果的实现方法
Dec 26 Javascript
vue2.0实战之基础入门(1)
Mar 27 Javascript
解决vue中post方式提交数据后台无法接收的问题
Aug 11 Javascript
通过js示例讲解时间复杂度与空间复杂度
Aug 06 Javascript
jQuery 查找元素操作实例小结
Oct 02 jQuery
npm qs模块使用详解
Feb 07 Javascript
javaScript Array api梳理
Mar 31 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开发中常用的三个表单验证函数使用小结
2010/03/03 PHP
phpMyAdmin 链接表的附加功能尚未激活问题的解决方法(已测)
2012/03/27 PHP
适用于抽奖程序、随机广告的PHP概率算法实例
2014/04/09 PHP
php中chdir()函数用法实例
2014/11/13 PHP
jquery插件制作教程 txtHover
2012/08/17 Javascript
JQuery入门—编写一个简单的JQuery应用案例
2013/01/03 Javascript
jQuery实用基础超详细介绍
2013/04/11 Javascript
jquery移动节点实例
2015/01/14 Javascript
基于jQuery实现美观且实用的倒计时实例代码
2015/12/30 Javascript
javascript 用函数实现继承详解
2016/05/28 Javascript
vue实现可增删查改的成绩单
2016/10/27 Javascript
jQuery实现的分页插件完整示例
2020/05/26 jQuery
Vue + ts实现轮播插件的示例
2020/11/10 Javascript
JavaScript中展开运算符及应用的实例代码
2021/01/14 Javascript
python获取beautifulphoto随机某图片代码实例
2013/12/18 Python
Python中的jquery PyQuery库使用小结
2014/05/13 Python
python利用不到一百行代码实现一个小siri
2017/03/02 Python
python设定并获取socket超时时间的方法
2019/01/12 Python
python实现网页自动签到功能
2019/01/21 Python
Scrapy-Redis结合POST请求获取数据的方法示例
2019/05/07 Python
pytorch中的卷积和池化计算方式详解
2020/01/03 Python
python环境下安装opencv库的方法
2020/03/05 Python
Django Path转换器自定义及正则代码实例
2020/05/29 Python
pandas将list数据拆分成行或列的实现
2020/12/13 Python
美国女士泳装店:Swimsuits For All
2017/03/02 全球购物
保送生自荐信范文
2013/10/06 职场文书
成人高等教育毕业生自我鉴定
2013/10/22 职场文书
《猴子种树》教学反思
2014/02/14 职场文书
祖国在我心中演讲稿600字
2014/09/23 职场文书
群众路线个人剖析材料及整改措施
2014/11/04 职场文书
明确岗位职责
2015/02/14 职场文书
2015年公司行政后勤工作总结
2015/05/20 职场文书
高二数学教学反思
2016/02/18 职场文书
Python如何把不同类型数据的json序列化
2021/04/30 Python
Python自动化之批量处理工作簿和工作表
2021/06/03 Python
MySQL中的隐藏列的具体查看
2021/09/04 MySQL