<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 241,  comments - 116,  trackbacks - 0

    JavaScript動態(tài)加載(JavaScript Object Dynamic Loading) - 之所以叫做動態(tài),是應為其有別與通常的靜態(tài)加載形式。

    典型的JavaScript靜態(tài)加載方式,是通過<script>標簽將我們可能需要的所有JS文件依次嵌入到一個HTML頁面中,當 瀏覽器執(zhí)行到<script> 標簽,就會到我們指定的地方去加載JavaScript并運行,這時,文件中定義的無論方法、類、對象等,已經(jīng)存在與瀏覽器,等待被使用。除非HTML頁 面被Unload,否則這些東西就一直存在。

    而典型的動態(tài)加載方式,是不需要任何提前的準備,只有當需要一個JavaScript對象來為我們服務時,我們就臨時去加載它所屬的JS文件,然后使用它,使用完畢,銷毀即可。正所謂“呼之即來,揮之即去”。

    就因為這“呼之即來,揮之即去”的能力,使得JavaScript真正的活了起來。

     

    JS動態(tài)加載解決了什么問題

    給系統(tǒng)減了肥:可以將不必要的JavaScript代碼延遲加載,未用到的功能不加載。 
    模塊化得以實現(xiàn):可以將原本大塊的功能或類,分解成合理的小塊,便于管理與維護。 
    方便的值傳遞:雙向傳值,無拘束。基于JSON,可以傳遞大對象。 
    可以實現(xiàn)Service:可以基于Service理念,通過核心JavaScript對象使用其他的服務功能對象,完成業(yè)務的組裝。 
    JS動態(tài)加載應該有什么能力

    可以異步的,或同步的,隨心所遇加載外部JS文件。 
    加載進來的JS文件的內(nèi)容可以有效管理,包括作用域,開放性,生命周期。 
    可以支持面向?qū)ο螅詫ο鬄榛军c而不是方法或變量等。 
    有好的封裝,可以通過一個句柄操作整個被加載的JS。 
    傳統(tǒng)JS動態(tài)加載的實現(xiàn)

    關于JS動態(tài)加載的實現(xiàn),我見過很多種方法。早期的時候,人們想過很多辦法。這些辦法有自己發(fā)揮的空間,可以解決一些問題。但是都或多或少的存在弊端,以及實現(xiàn)上的繁瑣,最大的問題就是,它們基本都不是面向?qū)ο蟮摹O旅婢土信e主要的2類:

    用嵌套iFrame的方式來加載JS文件:這種方式早期最多,通過在頁面中包含一個iFrame,來調(diào)用一個另一個包含了<script>標簽的HTML頁面,實現(xiàn)JS的動態(tài)加載。最大的弊端就是無法傳遞參數(shù),實現(xiàn)較繁瑣。 
    臨時創(chuàng)建<script>標簽:這種方式有很多人用。利用JavaScript操作頁面Dom模型,臨時創(chuàng)建一 個<script>標簽,然后appendChild到<body>上,或者動態(tài)改變已存在<scirpt>標簽的 src屬性。弊端是只能同步加載,必須等待JS文件被讀取完畢,才能進行下一步工作。且傳值是通過調(diào)用被加載的JS內(nèi)的變量實現(xiàn),雙向傳值困難,作用域弱 化。 
    可以看出以上兩種常見方式,都無法滿足我們的要求。

    更優(yōu)秀的解決方案

    得益于神奇如阿拉丁神燈般的 eval() ,我們就可以實現(xiàn)以上所有的愿望 :) 。

    繞了那么大圈子,想了那么多辦法。其實最簡單的方法就在眼皮底下.

    第一部分-調(diào)用方 main.js文件:

    //動態(tài)讀取JS對象的方法

    //@FileName :要讀取的JS對象URL,可以是本地路徑。

    //@TheParameters :需要傳遞給被加載對象的參數(shù),可以是任何對象。

    function loadJSObj(FileName,TheParameters){ 
        Ext.Ajax.request({   //異步調(diào)用方法 
            url: FileName,   //調(diào)用URL 
            scope: this,   
            success: function(response){   //成功后的回調(diào)方法response為返回內(nèi)容 
                var remoteObj = eval(response.responseText); 
                var mod = null; 
                mod = new remoteObj(TheParameters);

                return mod; 
            }, 
            failure:function(){   //失敗后的回調(diào)方法 
                alert(name+' - 讀取失敗,請檢查網(wǎng)絡或文件。');

                return null; 
            } 
        }); 
    }

    這段代碼使用Extjs類庫封裝的異步讀取方法Ext.Ajax.request()。只是為了方便。如果你使用未封裝的XMLHttpRequest對象也沒什么問題。

    先大概說下loadJSObj方法干的事情是:

    用XMLHttpRequest來了一次Ajax請求,將想要加載的JS文件源代碼讀過來。 
    利用eval函數(shù)將剛才讀到的遠程JavaScript類實例化成為本地的對象(期間傳遞了構造參數(shù))。 
    返回這個對象,供使用。 
    此處關鍵的代碼在于

                var remoteObj = eval(response.responseText); 
                var mod = null; 
                mod = new remoteObj(TheParameters);

                return mod;

    可以看到,我們直接將被讀取的JS文件傳進eval 函數(shù)執(zhí)行。并返回一個叫做 remoteObj的東西,這個東西其實就是被讀取的JS的句柄(一個類,定義在被讀取JS中的類,后面會詳細說到),通過將remoteObj實例化, 即mod = new remoteObj(參數(shù)) 就可以通過 mod 對象對被讀取的JS隨心所欲了操作了。

    如此一來,遠程的JS就被我們按照參數(shù)中指定的要求實例化成本地對象了,可以使用了。但是…這只是一相情愿。因為被讀取的JS得符合我們的要求,才能“兩廂情愿”,最終得到結果…

    第二部分 - 被調(diào)用方 login.js文件:

    要想符合要求,被讀取的JS文件也必須按照一定的規(guī)則來寫。

    //用戶登錄類

    Ext.extend(eueuy.module,{ 
        init:function(){    
            //==Variables==// 
            var userName = this.parameters.un;  //獲取傳遞進來的參數(shù)un 
            var passWord = this.parameters.pwd;   //獲取傳遞進來的參數(shù)pwd  
            
            //==Methods==// 
            //登錄方法 
            function loginOn(){ 
                if (userName=='eueuy' || passWord=='123'){  
                    return true;                
                }else{ 
                    return false; 
                } 
            } 
            //登出方法        
            function loginOff(){  
                alert('歡迎再來');

            } 
        } 
    });

    我們先看看這個登錄類干了什么:

    繼承自eueuy.moudle,并重寫了構造函數(shù)。 
    接收了2個傳遞進來的初始化參數(shù),un 和 pwd。 
    定義了2個成員方法和一個成員變量。 
    沒有任何特別的東西,就是Ext.extend方法用的有點怪,區(qū)別于平常的 XXX = Ext.extend();

    沒有賦值符號和類名。這恰恰是一個關鍵點:

    類的名字必須留空

    為什么這樣寫?因為這樣一來,這個沒有類名的類, 就可以在eval()函數(shù)執(zhí)行他的時候,再給他定義類名,這樣就將類名的定義留在了調(diào)用的時候,也就是main.js文件中。這個小技巧也將使調(diào)用方(main.js)可以直接控制被調(diào)用方(login.js)的類。

    最后,就可以在main.js中用下面的代碼,通過動態(tài)加載用戶登錄類,進行用戶登錄驗證的工作:

    var loginModel = loadJSObj('http://www.eueuy.name/project1/js/login.js',{un:’eueuy’,pwd:’123’});

    if (loginModel.loginOn()){

        alert('登錄成功,歡迎'+loginModel.userName);

    }else{

        alert('登錄失敗,錯誤的用戶名密碼');

    }

    可以看到,在上面的代碼中,我們通過loginModel這個變量,控制了login.js中的登錄類,可以訪問其中的方法loginOn() ,還可以訪問其中的變量 userName。第三方物流

     

    結尾

    至此,對象動態(tài)加載技術的理論已經(jīng)講解的差不多了,再下一篇博文中,我還會依據(jù)這些理論,給大家貼出一個基于動態(tài)加載的的項目框架。這個框架可以方便的實現(xiàn)One-Page,還可以看到一些具體的應用。

    posted on 2011-08-10 09:39 墻頭草 閱讀(1063) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     
    人人游戲網(wǎng) 軟件開發(fā)網(wǎng) 貨運專家
    主站蜘蛛池模板: 久久青青草原国产精品免费| 精品97国产免费人成视频 | 久久国产免费福利永久| 好看的亚洲黄色经典| 国产在线精品免费aaa片| 亚洲AV永久无码精品| 18禁男女爽爽爽午夜网站免费| 蜜芽亚洲av无码精品色午夜| 95老司机免费福利| 亚洲国语在线视频手机在线| 2021精品国产品免费观看 | 极品色天使在线婷婷天堂亚洲 | 亚洲一区无码中文字幕| 两性色午夜免费视频| 国产AV无码专区亚洲AV漫画| 黄网站免费在线观看| 亚洲性色高清完整版在线观看| 成年女人18级毛片毛片免费| 欧美色欧美亚洲另类二区| 亚洲精品乱码久久久久久蜜桃| 成在人线av无码免费高潮喷水 | 久久久久久亚洲精品无码| 亚洲国产成人久久综合碰| 最近的2019免费中文字幕| 久久亚洲AV成人无码| 久久WWW色情成人免费观看| 无遮挡呻吟娇喘视频免费播放| 自拍偷自拍亚洲精品情侣| 中文字幕免费视频一| 亚洲第一街区偷拍街拍| 精品亚洲一区二区三区在线观看| 亚洲成人免费在线| 人人狠狠综合久久亚洲| 亚洲av无码片在线播放| 免费鲁丝片一级在线观看| 免费无码黄网站在线看| 亚洲人成人网毛片在线播放| 亚洲精品成人a在线观看| 色片在线免费观看| 国产免费久久久久久无码| 亚洲免费观看网站|