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 全角转换实现代码
Jul 17 Javascript
如何将php数组或者对象传递给javascript
Mar 20 Javascript
js使用ajax读博客rss示例
May 06 Javascript
jQuery对象的selector属性用法实例
Dec 27 Javascript
JS常用正则表达式总结【经典】
May 12 Javascript
easyUI下拉列表点击事件使用方法
May 18 Javascript
详解Angular结合zTree异步加载节点数据
Jan 20 Javascript
详解vue 单页应用(spa)前端路由实现原理
Apr 04 Javascript
vue this.reload 方法 配置
Sep 12 Javascript
vue自动路由-单页面项目(非build时构建)
Apr 30 Javascript
微信小程序关键字变色实现代码实例
Dec 13 Javascript
vue-cli3 热更新配置操作
Sep 18 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中使用sockets:从新闻组中获取文章
2006/10/09 PHP
php面向对象全攻略 (六)__set() __get() __isset() __unset()的用法
2009/09/30 PHP
php+xml实现在线英文词典之添加词条的方法
2015/01/23 PHP
PHP+Mysql分布式事务与解决方案深入理解
2021/02/27 PHP
javascript window对象属性整理
2009/10/24 Javascript
php gethostbyname获取域名ip地址函数详解
2010/01/24 Javascript
自写简单JS判断是否已经弹出页面
2010/10/20 Javascript
js的2种继承方式详解
2014/03/04 Javascript
Javascript中的数据类型之旅
2015/10/18 Javascript
详解使用JS如何制作简单的ASCII图与单极图
2017/03/31 Javascript
bootstrap table插件的分页与checkbox使用详解
2017/07/23 Javascript
微信小程序实现弹出菜单
2018/07/19 Javascript
图文详解vue框架安装步骤
2019/02/12 Javascript
vue过滤器用法实例分析
2019/03/15 Javascript
js实现浏览器打印功能的示例代码
2020/07/15 Javascript
javascript前端和后台进行数据交互方法示例
2020/08/07 Javascript
理解Python中的With语句
2015/02/02 Python
Python操作串口的方法
2015/06/17 Python
详解Python中表达式i += x与i = i + x是否等价
2017/02/08 Python
python实现一个函数版的名片管理系统过程解析
2019/08/27 Python
解决Keras 中加入lambda层无法正常载入模型问题
2020/06/16 Python
学python最电脑配置有要求么
2020/07/05 Python
OpenCV4.1.0+VS2017环境配置的方法步骤
2020/07/09 Python
python 实现图片修复(可用于去水印)
2020/11/19 Python
python 获取计算机的网卡信息
2021/02/18 Python
html+js 实现markdown编辑器效果
2019/10/23 HTML / CSS
澳大利亚儿童精品仓库:Goo & Co.
2019/06/20 全球购物
正宗的日本零食和糖果订阅盒:Bokksu
2019/11/21 全球购物
高级Java程序员面试题
2016/06/23 面试题
项目经理的岗位职责
2013/11/23 职场文书
客服专员岗位职责
2014/02/28 职场文书
绩效管理实施方案
2014/03/19 职场文书
面试自我评价范文
2014/09/17 职场文书
2015年学校德育工作总结
2015/04/22 职场文书
律师函格式范本
2015/05/27 职场文书
2015年社区反邪教工作总结
2015/10/14 职场文书