javascript 模拟JQuery的Ready方法实现并出现的问题

 更新时间:2009年12月06日 00:55:13   作者:  
今天在阅读网上一些模拟Jq的ready方法时,发现一些小细节,就是网上的ready事件大部分都是在onload事件执行后加载,而jquery确能在onload加载前。
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();
}
});
}
}
}

相关文章

  • js怎么判断是否是数组的六种方法小结

    js怎么判断是否是数组的六种方法小结

    本文主要介绍了js怎么判断是否是数组的六种方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • 详解javascript appendChild()的完整功能

    详解javascript appendChild()的完整功能

    这篇文章主要介绍了详解javascript appendChild()的完整功能,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • js裁剪(分隔)字符串的三种常用方法

    js裁剪(分隔)字符串的三种常用方法

    在开发中我们经常会遇到对于字符串的部分取舍问题,本文主要介绍了js裁剪(分隔)字符串的三种常用方法,今天我们来看看3中常用的方法来解决这个问题,感兴趣的可以一起了解一下
    2022-02-02
  • 详解JavaScript实现动态的轮播图效果

    详解JavaScript实现动态的轮播图效果

    这篇文章主要介绍了JavaScript实现动态的轮播图效果,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • 跟我学习javascript的全局变量

    跟我学习javascript的全局变量

    跟我学习javascript的全局变量,告诉大家三种避免全局变量的方法,感兴趣的小伙伴们可以参考一下
    2015-11-11
  • 用document.documentElement取代document.body的原因分析

    用document.documentElement取代document.body的原因分析

    ll建议用document.documentElement代替document.body
    2009-11-11
  • bootstrap时间插件daterangepicker使用详解

    bootstrap时间插件daterangepicker使用详解

    这篇文章主要为大家详细介绍了bootstrap时间插件daterangepicker使用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • html代码调试脚本

    html代码调试脚本

    html代码调试脚本...
    2006-07-07
  • javascript实现添加附件功能的方法

    javascript实现添加附件功能的方法

    这篇文章主要介绍了javascript实现添加附件功能的方法,在我们编辑信息时,有时候需要附加文件、图片实现上传功能,通过本文了解javascript是如何实现附加功能的,请阅读。
    2015-11-11
  • JavaScript面向对象之体会[总结]

    JavaScript面向对象之体会[总结]

    看过很多JavaScript书,对JavaScript的面向对象讲的都比较深入,但是并没有做到深入浅出,总结了我做的一些JavaScript程序的经验,以简洁明了的文字使大家明白JavaScript面向对象的实现。
    2008-11-11

最新评论