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 08 Javascript
20个最新的jQuery插件
Jan 13 Javascript
JavaScript的事件绑定(方便不支持js的时候)
Oct 01 Javascript
JQuery文字列表向上滚动的代码
Nov 13 Javascript
对 jQuery 中 data 方法的误解分析
Jun 18 Javascript
JavaScript实现文字与图片拖拽效果的方法
Feb 16 Javascript
javascript实现框架高度随内容改变的方法
Jul 23 Javascript
JS实现Fisheye效果动感放大菜单代码
Oct 21 Javascript
jQuery图片左右滚动代码 有左右按钮实例
Jun 20 Javascript
bootstrap实现动态进度条效果
Mar 08 Javascript
jquery.masonry瀑布流效果
May 25 jQuery
vue template中slot-scope/scope的使用方法
Sep 06 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生成HTML静态页面实例代码
2008/08/31 PHP
php笔记之常用文件操作
2010/10/12 PHP
关于php内存不够用的快速解决方法
2013/10/26 PHP
TP5(thinkPHP5)框架基于ajax与后台数据交互操作简单示例
2018/09/03 PHP
PHP的mysqli_ssl_set()函数讲解
2019/01/23 PHP
PHP论坛实现积分系统的思路代码详解
2020/06/01 PHP
把html页面的部分内容保存成新的html文件的jquery代码
2009/11/12 Javascript
javascript 跨浏览器开发经验总结(五) js 事件
2010/05/19 Javascript
复制Input内容的js代码_支持所有浏览器,修正了Firefox3.5以上的问题
2010/06/21 Javascript
JavaScript 高级篇之DOM文档,简单封装及调用、动态添加、删除样式(六)
2012/04/07 Javascript
javascript编写贪吃蛇游戏
2015/07/07 Javascript
JavaScript简单修改窗口大小的方法
2015/08/03 Javascript
一系列Bootstrap导航条使用方法分享
2016/04/29 Javascript
webpack 静态资源集中输出的方法示例
2018/11/09 Javascript
vue项目中使用AES实现密码加密解密(ECB和CBC两种模式)
2019/08/12 Javascript
layui自己添加图片按钮并点击跳转页面的例子
2019/09/14 Javascript
如何利用node.js开发一个生成逐帧动画的小工具
2019/12/01 Javascript
js实现蒙版效果
2020/01/11 Javascript
搭建vscode+vue环境的详细教程
2020/08/31 Javascript
[59:35]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#1COL VS Alliance第二局
2016/03/04 DOTA
[01:10:49]Secret vs VGJ.S 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
Python简单获取自身外网IP的方法
2016/09/18 Python
详解Django的CSRF认证实现
2018/10/09 Python
django template实现定义临时变量,自定义赋值、自增实例
2020/07/12 Python
Python自动发送和收取邮件的方法
2020/08/12 Python
python使用matplotlib的savefig保存时图片保存不完整的问题
2021/01/08 Python
CSS 3.0 结合video视频实现的创意开幕效果
2020/06/01 HTML / CSS
什么是Smart Navigation?
2016/07/03 面试题
const和static readonly区别
2013/05/20 面试题
什么是makefile? 如何编写makefile?
2013/01/02 面试题
Linux文件操作命令都有哪些
2016/07/23 面试题
公职人员索取回扣检举信
2014/04/04 职场文书
专家推荐信模板
2014/05/09 职场文书
无刑事犯罪记录证明
2014/09/18 职场文书
防火标语大全
2014/10/06 职场文书
Vue实现tab导航栏并支持左右滑动功能
2021/06/28 Vue.js