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各种复制代码收集
Sep 20 Javascript
JS 常用校验函数
Mar 26 Javascript
jQuery 全选/反选以及单击行改变背景色实例
Jul 02 Javascript
JavaScript获取某年某月的最后一天附截图
Jun 23 Javascript
JavaScript 2048 游戏实例代码(简单易懂)
Mar 25 Javascript
使用BootStrap进行轮播图的制作
Jan 06 Javascript
js仿百度音乐全选操作
Jan 13 Javascript
详解vue.js之绑定class和style的示例代码
Aug 24 Javascript
详解Vue-cli代理解决跨域问题
Sep 27 Javascript
对angularJs中controller控制器scope父子集作用域的实例讲解
Oct 08 Javascript
JavaScript 面向对象程序设计详解【类的创建、实例对象、构造函数、原型等】
May 12 Javascript
微信小程序自定义联系人弹窗
May 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
不用数据库的多用户文件自由上传投票系统(2)
2006/10/09 PHP
echo(),print(),print_r()之间的区别?
2006/11/19 PHP
浅析PHP7新功能及语法变化总结
2016/06/17 PHP
php使用gd2绘制基本图形示例(直线、圆、正方形)
2017/02/15 PHP
php中的explode()函数实例介绍
2019/01/18 PHP
PHP7实现和CryptoJS的AES加密方式互通示例【AES-128-ECB加密】
2019/06/08 PHP
使用prototype.js进行异步操作
2007/02/07 Javascript
使用JavaScript switch case 另类写法
2010/03/14 Javascript
在IE 浏览器中使用 jquery的fadeIn() 效果 英文字符字体加粗
2011/06/02 Javascript
使用mini-define实现前端代码的模块化管理
2014/12/25 Javascript
EasyUI,点击开启编辑框,并且编辑框获得焦点的方法
2015/03/01 Javascript
JS实现跟随鼠标立体翻转图片的方法
2015/05/04 Javascript
js过滤HTML标签完整实例
2015/11/26 Javascript
JS控制静态页面之间传递参数获取参数并应用的简单实例
2016/08/10 Javascript
node.js中 stream使用教程
2016/08/28 Javascript
javascript 正则表达式去空行方法
2017/01/24 Javascript
简单实现js无缝滚动效果
2017/02/05 Javascript
js每隔两秒输出数组中的一项(实例)
2017/05/28 Javascript
jQuery选择器之属性过滤选择器详解
2017/09/28 jQuery
三分钟学会用ES7中的Async/Await进行异步编程
2018/06/14 Javascript
JS执行控制之节流模式实例分析
2018/12/21 Javascript
jquery简单实现纵向的无缝滚动代码实例
2019/04/01 jQuery
ligerUI的ligerDialog关闭刷新的方法
2019/09/27 Javascript
python3 判断列表是一个空列表的方法
2018/05/04 Python
python用win32gui遍历窗口并设置窗口位置的方法
2019/07/26 Python
Python二元赋值实用技巧解析
2019/10/25 Python
python各层级目录下import方法代码实例
2020/01/20 Python
image-set实现Retina屏幕下图片显示详细介绍
2012/12/24 HTML / CSS
如何保障Web服务器安全
2014/05/05 面试题
Linux机考试题
2015/07/17 面试题
股份转让协议书
2014/04/12 职场文书
工程项目经理任命书
2014/06/05 职场文书
学校学雷锋活动总结
2014/06/26 职场文书
重阳节活动总结
2014/08/27 职场文书
《普罗米修斯》教学反思
2016/02/22 职场文书
Python 数据可视化之Bokeh详解
2021/11/02 Python