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

今天在阅读网上一些模拟Jq的ready方法时,发现一些小细节,就是网上的ready事件大部分都是在onload事件执行后加载,而jquery确能在onload加载前,dom加载完后执行,一直不了解,基于对网上的一些方法逻辑不了解,所以去看了《jquery源代码研究(ready函数) 》这篇文章后自己写入如下代码(已有详细说明):

 

ExpandedBlockStart.gif 代码
<! 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=utf-8 "   / >
< 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的结构,但是还是不能达到目的,难道中间有漏?

转载于:https://www.cnblogs.com/wbkt2t/archive/2009/12/04/1617159.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值