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 轻松支持函数重载 (Part 2 - 实现)
Aug 04 Javascript
jquery.lazyload  实现图片延迟加载jquery插件
Feb 06 Javascript
QUnit jQuery的TDD框架
Nov 04 Javascript
ASP.NET jQuery 实例6 (实现CheckBoxList成员全选或全取消)
Jan 13 Javascript
一个获取第n个元素节点的js函数
Sep 02 Javascript
JS应用正则表达式转换大小写示例
Sep 18 Javascript
js实现异步循环实现代码
Feb 16 Javascript
AngularJS实现ajax请求的方法
Nov 22 Javascript
jQuery基于ajax操作json数据简单示例
Jan 05 Javascript
webpack4 SplitChunks实现代码分隔详解
May 23 Javascript
Vue实现图片轮播组件思路及实例解析
May 11 Javascript
nuxt 实现在其它js文件中使用store的方式
Nov 05 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 Mysql类 可以参考学习熟悉下
2009/06/21 PHP
paypal即时到账php实现代码
2010/11/28 PHP
php遍历删除整个目录及文件的方法
2015/03/13 PHP
layui框架实现文件上传及TP3.2.3(thinkPHP)对上传文件进行后台处理操作示例
2018/05/12 PHP
php中目录操作opendir()、readdir()及scandir()用法示例
2019/06/08 PHP
一个可拖拽列宽表格实例演示
2012/11/26 Javascript
实测jquery data()如何存值
2013/08/18 Javascript
兼容主流浏览器的JS复制内容到剪贴板
2014/12/12 Javascript
javascript中String对象的slice()方法分析
2014/12/20 Javascript
JavaScript事件委托实例分析
2015/05/26 Javascript
jquery事件的ready()方法使用详解
2015/11/11 Javascript
jQuery实现移动端滑块拖动选择数字效果
2015/12/24 Javascript
微信小程序常用简易小函数总结
2019/02/01 Javascript
聊聊Vue中provide/inject的应用详解
2019/11/10 Javascript
微信小程序通过websocket实时语音识别的实现代码
2020/08/19 Javascript
小程序实现录音功能
2020/09/22 Javascript
vue-video-player视频播放器使用配置详解
2020/10/23 Javascript
[01:00:52]2018DOTA2亚洲邀请赛 4.4 淘汰赛 EG vs LGD 第一场
2018/04/05 DOTA
编写自定义的Django模板加载器的简单示例
2015/07/21 Python
Python星号*与**用法分析
2018/02/02 Python
Django之路由层的实现
2019/09/09 Python
python可以用哪些数据库
2020/06/22 Python
浅析Python 抽象工厂模式的优缺点
2020/07/13 Python
一款纯css3实现的竖形二级导航的实例教程
2014/12/11 HTML / CSS
mui几种页面跳转方式对比总结概括
2017/08/18 HTML / CSS
美国半成品食材配送服务商:Home Chef
2018/01/25 全球购物
房地产销售计划书
2014/01/10 职场文书
团拜会策划方案
2014/06/07 职场文书
临床医学专业求职信
2014/08/08 职场文书
党性分析自查总结
2014/10/14 职场文书
个人年终总结怎么写
2015/03/09 职场文书
物业公司管理制度
2015/08/05 职场文书
创业计划书之餐饮馄饨店
2019/07/18 职场文书
Java 在生活中的 10 大应用
2021/11/02 Java/Android
spring IOC容器的Bean管理XML自动装配过程
2022/05/30 Java/Android
java获取一个文本文件的编码(格式)信息
2022/09/23 Java/Android