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 相关文章推荐
常用参考资料(手册)下载或者链接
Jul 22 Javascript
JQuery从头学起第三讲
Jul 06 Javascript
Javascript计算时间差的函数分享
Jul 04 Javascript
jquery聚焦文本框与扩展文本框聚焦方法
Oct 12 Javascript
js判断鼠标左、中、右键哪个被点击的方法
Jan 27 Javascript
JavaScript比较两个数组的内容是否相同(推荐)
May 02 Javascript
浅谈vue+webpack项目调试方法步骤
Sep 11 Javascript
three.js中文文档学习之创建场景
Nov 20 Javascript
jQuery+vue.js实现的多选下拉列表功能示例
Jan 15 jQuery
Vue实现搜索结果高亮显示关键字
May 28 Javascript
微信小程序事件 bindtap bindinput代码实例
Aug 26 Javascript
layui.tree组件的使用以及搜索节点功能的实现
Sep 26 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
codeigniter教程之多文件上传使用示例
2014/02/11 PHP
PHP SPL标准库之SplFixedArray使用实例
2015/05/12 PHP
PHP模板引擎Smarty之配置文件在模板变量中的使用方法示例
2016/04/11 PHP
PHP CURL post数据报错 failed creating formpost data
2016/10/16 PHP
PHP自动识别当前使用移动终端
2018/05/21 PHP
ASP中用Join和Array,可以加快字符连接速度的代码
2007/08/22 Javascript
JQuery 表格操作(交替显示、拖动表格行、选择行等)
2009/07/29 Javascript
js中的值类型和引用类型小结 文字说明与实例
2010/12/12 Javascript
JavaScript动态改变表格单元格内容的方法
2015/03/30 Javascript
CSS javascript 结合实现悬浮固定菜单效果
2015/08/23 Javascript
Bootstrap每天必学之基础排版
2015/11/20 Javascript
js省市联动效果完整实例代码
2015/12/09 Javascript
javascript实现html页面之间参数传递的四种方法实例分析
2015/12/15 Javascript
浅析JavaScript中浏览器的兼容问题
2016/04/19 Javascript
jQuery扩展实现text提示还能输入多少字节的方法
2016/11/28 Javascript
BootStrap Validator 版本差异问题导致的submitHandler失效问题的解决方法
2016/12/01 Javascript
vue2.0父子组件及非父子组件之间的通信方法
2017/01/21 Javascript
ES6使用Set数据结构实现数组的交集、并集、差集功能示例
2017/10/31 Javascript
vue内置组件keep-alive事件动态缓存实例
2020/10/30 Javascript
[03:00]2018完美盛典_最佳英雄奖
2018/12/17 DOTA
Python open读写文件实现脚本
2008/09/06 Python
python定时检查启动某个exe程序适合检测exe是否挂了
2013/01/21 Python
简单介绍Python下自己编写web框架的一些要点
2015/04/29 Python
Python 功能和特点(新手必学)
2015/12/30 Python
ubuntu中配置pyqt4环境教程
2017/12/27 Python
使用Matplotlib 绘制精美的数学图形例子
2019/12/13 Python
python怎么自定义捕获错误
2020/06/29 Python
Python监听剪切板实现方法代码实例
2020/11/11 Python
Canvas实现保存图片到本地的示例代码
2018/06/28 HTML / CSS
英国Amara家居法国网站:家居装饰,现代装饰和豪华礼品
2016/12/15 全球购物
伦敦眼门票在线预订:London Eye
2018/05/31 全球购物
自动一体化专业求职信
2014/03/15 职场文书
2014年党的群众路线整改措施思想汇报
2014/10/12 职场文书
西安大雁塔导游词
2015/02/10 职场文书
i5-10400f处理相当于i7多少水平
2022/04/19 数码科技
小程序实现侧滑删除功能
2022/06/25 Javascript