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 相关文章推荐
指定js可访问其它域名的cookie的方法
Sep 18 Javascript
jquery 将disabled的元素置为enabled的三种方法
Jul 25 Javascript
javascript数组的使用
Mar 28 Javascript
jQuery :first选择器使用介绍
Aug 09 Javascript
jQuery动态创建html元素的常用方法汇总
Sep 05 Javascript
JQuery实现防止退格键返回的方法
Feb 12 Javascript
js滑动提示效果代码分享
Mar 10 Javascript
原生js的数组除重复简单实例
May 24 Javascript
AngularJS基础 ng-options 指令详解
Aug 02 Javascript
JS瀑布流实现方法实例分析
Dec 19 Javascript
浅谈高大上的微信小程序中渲染html内容—技术分享
Oct 25 Javascript
Vue+Element-U实现分页显示效果
Nov 15 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顺序查找和二分查找示例
2014/03/27 PHP
PHP之浮点数计算比较以及取整数不准确的解决办法
2015/07/29 PHP
PHP面向对象程序设计组合模式与装饰模式详解
2016/12/02 PHP
laravel中命名路由的使用方法
2017/02/24 PHP
Js 获取Gridview选中行的内容操作步骤
2013/02/05 Javascript
用客户端js实现带省略号的分页
2013/04/27 Javascript
jQuery中操控hidden、disable等无值属性的方法
2014/01/06 Javascript
表单提交前触发函数返回true表单才会提交
2014/03/11 Javascript
js设置控件的隐藏与显示的两种方法
2014/08/21 Javascript
JS获取时间的方法
2015/01/21 Javascript
深入理解js promise chain
2016/05/05 Javascript
jQuery.cookie.js实现记录最近浏览过的商品功能示例
2017/01/23 Javascript
浅析jsopn跨域请求原理及cors(跨域资源共享)的完美解决方法
2017/02/06 Javascript
详解vue-cli中配置sass
2017/06/21 Javascript
jQuery UI Draggable + Sortable 结合使用(实例讲解)
2017/09/07 jQuery
浅谈小程序 setData学问多
2019/02/20 Javascript
vue+ESLint 配置保存 自动格式化代码
2020/03/17 Javascript
Python实现端口复用实例代码
2014/07/03 Python
python实现颜色rgb和hex相互转换的函数
2015/03/19 Python
python实现壁纸批量下载代码实例
2018/01/25 Python
python 删除列表里所有空格项的方法总结
2018/04/18 Python
对Python3 序列解包详解
2019/02/16 Python
Python实现从SQL型数据库读写dataframe型数据的方法【基于pandas】
2019/03/18 Python
Python爬虫抓取指定网页图片代码实例
2020/07/24 Python
PyQt5 QDockWidget控件应用详解
2020/08/12 Python
python 使用三引号时容易犯的小错误
2020/10/21 Python
用python制作个音乐下载器
2021/01/30 Python
荷兰家电购物网站:Expert.nl
2020/01/18 全球购物
金智子午JAVA面试题
2015/09/04 面试题
《守株待兔》教学反思
2014/03/01 职场文书
实习推荐信
2014/05/10 职场文书
道路交通事故赔偿协议书
2014/10/24 职场文书
2015年副班长工作总结
2015/05/15 职场文书
python获取字符串中的email
2022/03/31 Python
VUE使用draggable实现组件拖拽
2022/04/06 Vue.js
人工智能深度学习OpenAI baselines的使用方法
2022/05/20 Python