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操作XML 使用百度RSS作为新闻源示例
Feb 17 Javascript
fmt:formatDate的输出格式详解
Jan 09 Javascript
基于JavaScript实现在新的tab页打开url
Aug 04 Javascript
JS 全屏和退出全屏详解及实例代码
Nov 07 Javascript
easyui取消表单实时验证,提交时统一验证的简单实例
Nov 07 Javascript
基于jQuery的checkbox全选问题分析
Nov 18 Javascript
vue.js实现仿原生ios时间选择组件实例代码
Dec 21 Javascript
ES6新特性之模块Module用法详解
Apr 01 Javascript
jQuery+pjax简单示例汇总
Apr 21 jQuery
深入理解react-router 路由的实现原理
Sep 26 Javascript
arctext.js实现文字平滑弯曲弧形效果的插件
May 13 Javascript
vue.js watch经常失效的场景与解决方案
Jan 07 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
php 验证码制作(网树注释思想)
2009/07/20 PHP
php获取汉字拼音首字母的方法
2015/10/21 PHP
详解Yii2 rules 的验证规则
2016/12/02 PHP
php函数式编程简单示例
2019/08/08 PHP
laravel在中间件内生成参数并且传递到控制器中的2种姿势
2019/10/15 PHP
js传值 判断
2006/10/26 Javascript
关于Ext中form移除textfield方法:hide(),setVisible(false),remove()
2010/12/02 Javascript
JavaScript中判断函数是new还是()调用的区别说明
2011/04/07 Javascript
jQuery 源码分析笔记(6) jQuery.data
2011/06/08 Javascript
NodeJS url验证(url-valid)的使用方法
2013/11/18 NodeJs
window.open 以post方式传递参数示例代码
2014/02/27 Javascript
javascript 中that的含义示例介绍
2014/05/14 Javascript
jQuery打印指定区域Html页面并自动分页
2014/07/04 Javascript
ECMAScript6中Map/WeakMap详解
2015/06/12 Javascript
AngularJS实现分页显示数据库信息
2016/07/01 Javascript
基于jQuery实现的幻灯图片切换
2016/12/02 Javascript
JavaScript的事件机制详解
2017/01/17 Javascript
Easyui Datagrid自定义按钮列(最后面的操作列)
2017/07/13 Javascript
jQuery EasyUI 折叠面板accordion的使用实例(分享)
2017/12/25 jQuery
Webpack实战加载SVG的方法
2017/12/26 Javascript
vue项目实现表单登录页保存账号和密码到cookie功能
2018/08/31 Javascript
jQuery轻量级表单模型验证插件
2018/10/15 jQuery
一文搞懂ES6中的Map和Set
2019/05/20 Javascript
使用layui+ajax实现简单的菜单权限管理及排序的方法
2019/09/10 Javascript
Vue和React有哪些区别
2020/09/12 Javascript
[02:21]2018完美盛典章节片——初心
2018/12/17 DOTA
[02:50]【扭转乾坤,只此一招】DOTA2永雾林渊版本开启新篇章
2020/12/22 DOTA
python爬虫框架scrapy实战之爬取京东商城进阶篇
2017/04/24 Python
Linux下Pycharm、Anaconda环境配置及使用踩坑
2018/12/19 Python
Python Numpy库安装与基本操作示例
2019/01/08 Python
使用Python自动化破解自定义字体混淆信息的方法实例
2019/02/13 Python
python破解同事的压缩包密码
2020/10/14 Python
佛罗里达州印第安河新鲜水果:Hale Groves
2017/02/20 全球购物
数控技校生自我鉴定
2014/03/02 职场文书
基于Python实现一个春节倒计时脚本
2022/01/22 Python
Vue自定义铃声提示音组件的实现
2022/01/22 Vue.js