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 相关文章推荐
Firefox中beforeunload事件的实现缺陷浅析
May 03 Javascript
jquery 动态创建元素的方式介绍及应用
Apr 21 Javascript
JavaScript函数获取事件源的小例子
May 14 Javascript
JS和JQ的event对象区别分析
Nov 24 Javascript
JS+CSS实现的简单折叠展开多级菜单效果
Sep 12 Javascript
利用jQuery和CSS将背景图片拉伸
Oct 16 Javascript
node.js路径处理方法以及绝对路径详解
Mar 04 Javascript
Javascript 正则表达式校验数字的简单实例
Nov 02 Javascript
jQuery 利用ztree实现树形表格的实例代码
Sep 27 jQuery
Javascript中从学习bind到实现bind的过程
Jan 05 Javascript
对vue 键盘回车事件的实例讲解
Aug 25 Javascript
vue组件通信传值操作示例
Jan 08 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
PHP4实际应用经验篇(2)
2006/10/09 PHP
解析如何通过PHP函数获取当前运行的环境 来进行判断执行逻辑(小技巧)
2013/06/25 PHP
PHP字符串中特殊符号的过滤方法介绍
2014/02/18 PHP
针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例
2018/06/16 PHP
将string解析为json的几种方式小结
2010/11/11 Javascript
firefox下input type=&quot;file&quot;的size是多大
2011/10/24 Javascript
angular.element方法汇总
2015/01/07 Javascript
JS+DIV实现鼠标划过切换层效果的方法
2015/05/25 Javascript
轻量级jQuery插件slideBox实现带底栏轮播(焦点图)代码
2016/03/28 Javascript
BootStrap学习系列之Bootstrap Typeahead 组件实现百度下拉效果(续)
2016/07/07 Javascript
微信小程序 template模板详解及实例
2017/02/21 Javascript
详解使用angular-cli发布i18n多国语言Angular应用
2017/05/20 Javascript
JavaScript中document.referrer的用法详解
2017/07/04 Javascript
JS判断微信扫码的方法
2017/08/07 Javascript
JS实现移动端整屏滑动的实例代码
2017/11/10 Javascript
纯JS实现出生日期[年月日]下拉菜单效果
2018/06/01 Javascript
基于nodejs的雪碧图制作工具的示例代码
2018/11/05 NodeJs
在vue中使用express-mock搭建mock服务的方法
2018/11/07 Javascript
详解如何用webpack4从零开始构建react开发环境
2019/01/27 Javascript
layer.alert回调函数执行关闭弹窗的实例
2019/09/11 Javascript
json_decode 索引为数字时自动排序问题解决方法
2020/03/28 Javascript
解决python写的windows服务不能启动的问题
2014/04/15 Python
python和flask中返回JSON数据的方法
2018/03/26 Python
Python数据预处理之数据规范化(归一化)示例
2019/01/08 Python
tensorflow模型文件(ckpt)转pb文件的方法(不知道输出节点名)
2020/04/22 Python
Html5页面中的返回实现的方法
2018/02/26 HTML / CSS
super关键字的用法
2012/04/10 面试题
C和C++经典笔试题附答案解析
2014/08/18 面试题
Linux如何命名文件--使用文件名时应注意
2014/05/29 面试题
大学生预备党员自我评价分享
2013/11/16 职场文书
期终自我鉴定
2014/02/17 职场文书
党员廉洁自律承诺书
2014/05/26 职场文书
忠犬八公的故事观后感
2015/06/05 职场文书
2016年学校党支部创先争优活动总结
2016/04/05 职场文书
手把手教你制定暑期学习计划,让你度过充实的暑假
2019/08/22 职场文书
Python捕获、播放和保存摄像头视频并提高视频清晰度和对比度
2022/04/14 Python