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 相关文章推荐
使用jQuery简化Ajax开发 Ajax开发入门
Oct 14 Javascript
jquery移除button的inline onclick事件(已测试及兼容浏览器)
Jan 25 Javascript
javascript中的if语句使用介绍
Nov 20 Javascript
JavaScript实现的石头剪刀布游戏源码分享
Aug 22 Javascript
JavaScript错误处理
Feb 03 Javascript
jQuery简单实现仿京东商城的左侧菜单效果代码
Sep 09 Javascript
使用jQuery Mobile框架开发移动端Web App的入门教程
May 17 Javascript
jQuery对checkbox 复选框的全选全不选反选的操作
Aug 09 Javascript
Easyui Datagrid自定义按钮列(最后面的操作列)
Jul 13 Javascript
微信小程序实现通过js操作wxml的wxss属性示例
Dec 06 Javascript
使用Layer组件弹出多个对话框(非嵌套)与关闭及刷新的例子
Sep 25 Javascript
vue 中this.$set 动态绑定数据的案例讲解
Jan 29 Vue.js
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
yii框架表单模型使用及以数组形式提交表单数据示例
2014/04/30 PHP
浅谈discuz密码加密的方式
2014/05/22 PHP
科讯商业版中用到的ajax空间与分页函数
2007/09/02 Javascript
js 字符串操作函数
2009/07/25 Javascript
jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera
2009/08/28 Javascript
JQuery SELECT单选模拟jQuery.select.js
2009/11/12 Javascript
JavaScript 学习笔记(十三)Dom创建表格
2010/01/21 Javascript
Javascript中的变量使用说明
2010/05/18 Javascript
ExtJs事件机制基本代码模型和流程解析
2010/10/24 Javascript
DOM2非标准但却支持很好的几个属性小结
2012/01/21 Javascript
DWZ table的原生分页浅谈
2013/03/01 Javascript
js将控件隐藏的方法及display属性介绍
2013/07/04 Javascript
JS的事件绑定深入认识
2014/06/26 Javascript
JS实现的自定义水平滚动字体插件完整实例
2016/06/17 Javascript
JQuery 获取多个select标签option的text内容(实例)
2017/09/07 jQuery
node前端开发模板引擎Jade的入门
2018/05/11 Javascript
微信小程序swiper实现滑动放大缩小效果
2018/11/15 Javascript
vue-router的hooks用法详解
2020/06/08 Javascript
vue 公共列表选择组件,引用Vant-UI的样式方式
2020/11/02 Javascript
采用python实现简单QQ单用户机器人的方法
2014/07/03 Python
Python中Random和Math模块学习笔记
2015/05/18 Python
Python生成指定数量的优惠码实操内容
2019/06/18 Python
django实现将修改好的新模型写入数据库
2020/03/31 Python
室内设计自我鉴定
2013/10/15 职场文书
公司活动总结怎么写
2014/06/25 职场文书
中职三好学生事迹材料
2014/08/24 职场文书
二人合伙经营协议书
2014/09/13 职场文书
2014年帮扶工作总结
2014/11/26 职场文书
2014年销售人员工作总结
2014/11/27 职场文书
大连星海广场导游词
2015/02/10 职场文书
2015国际残疾人日活动总结
2015/03/24 职场文书
2015员工年度考核评语
2015/03/25 职场文书
公司酒会主持词
2015/07/02 职场文书
2015大学生暑期实习报告
2015/07/13 职场文书
nginx 防盗链防爬虫配置详解
2021/03/31 Servers
python中sys模块的介绍与实例
2021/04/17 Python