DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> javascript動態加載實現方法一
javascript動態加載實現方法一
編輯:關於JavaScript     
現在也有很多JS動態加載的框架,比如In.js。但是這種並不是我想要的編寫方式,我來說說我的想法。

先來一段java代碼
復制代碼 代碼如下:
import Biz.User;
User u = new User();
u.show();

按流程就是導包、實例化、調用。

JS是做不了導包的,或者說代碼意義上的導包,一般只是在頁面上進行script標簽的引入。
那麼 先假設需要寫成這樣
復制代碼 代碼如下:
Using("User");
var u = new User();
u.show();

那麼,在JS裡面可以實現嗎?

來一句一句的分析,當然,前提是頁面並不用script標簽載入user.js,不然就沒意義了。

第一句

Using("User");

為什麼用Using,當然只是我的一個命名想法而已,可以聯想一下C#,用的就是using,借來而已。

Using裡面寫入的當然是我需要的對象User,顧名思義,我當然寫成Using("User")了。先不說內裡是怎麼實現的,起碼思路是這樣。
因為不能模擬關鍵字寫成 Using User;這種起碼我是做不到了。
第二句和第三句
復制代碼 代碼如下:
var u = new User();
u.show();

很正常,就是很平常的實例化與函數調用,唯一不解的是User對象哪裡來的?那麼當然是第一句導包的時候導入的。


流程就是這麼個流程,那麼到底能不能實現,關鍵就在第一句話。也就是說,到底能不能導包成功,而且該怎麼導包。

從script標簽吸引靈感,對,異步加載所需要的js文件。
也就是說
復制代碼 代碼如下:
Using("User");

相當於寫了一句
復制代碼 代碼如下:<script type="text/javascript" src="user.js"></script>

現在這麼看下來,這麼做有意義嗎?就為把script標簽寫成JS動態引入的?或者,只為少寫幾個字符?

當然不能,這麼做毫無意義!那要怎麼做?
先從效率來講。
如果一個頁面需要載入N多js文件的時候,如下
復制代碼 代碼如下:
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="view.js"></script>
<script type="text/javascript" src="register.js"></script>
<script type="text/javascript" src="validate.js"></script>
<script type="text/javascript" src="user.js"></script>
<script type="text/javascript" src="order.js"></script>
<script type="text/javascript" src="type.js"></script>

等等等等。

是不是很嚇人,那是相當嚇人,而且後期維護需要很高的成本,有多少頁面,可能就需要修改幾個頁面。那麼,當頁面只引入關鍵的幾個js文件,其他文件都采用動態載入的方式呢?
比如我們只需要載入jquery文件,然後調用
復制代碼 代碼如下:
$.getScript("user.js",function(){});

這樣,我們就做到頁面文件裡面只需要引入
復制代碼 代碼如下:
<script type="text/javascript" src="jquery.min.js"></script>

即可。
那麼這種寫法的壞處在哪裡?看一段代碼
復制代碼 代碼如下:
$.getScript("user.js",function(){
$.getScript("order.js",function(){
$.getScript("type.js",function(){
$.getScript("validate.js",function(){
// and so on..
});
});
});
});

PS:用In.js的watch函數是可以避免這種情況產生的。這不在本博文的考慮范圍了。

花眼嗎?還願意去對齊代碼嗎?即便有格式化工具,你還願意將閉合括號與哪個$.getScript對應嗎?當然不願意。
那麼,仿java的導包形式應聲而出。
復制代碼 代碼如下:
Using("User");
Using("Order");
Using("Type");
Using("Validate");
// and so on..

或者你願意,你可以
復制代碼 代碼如下:
Using("User","Type","Order","Validate",...);

寫法問題 無所謂。當然我推薦使用第一種方法,清晰。

導包之後,所有的用法不需要任何嵌套,正常使用。
復制代碼 代碼如下:
var u = new User();
var o = new Order();
// and so on..

但是會提出一個問題。假如異步的加載都在Using("XXX")的時候執行,那麼
復制代碼 代碼如下:
Using("User");
Using("Order");
Using("Type");
Using("Validate");
// and so on..

這一段我就需要異步載入4個文件,雖然是異步的,但是未免有些麻煩?而且需要創建4個鏈接。你願意合並JS的話,也可以。而且,Using的時候我是不需要使用對象的,這個時候未免太浪費資源了?

至於這個問題,我的解決辦法就是學習hibernate,延遲加載,按需加載。
那麼怎麼做呢?
復制代碼 代碼如下:
Using("User");

這個時候肯定是不加載,不加載做什麼?當然是返回一個mock,也就是模擬對象。給用戶先用著,只有當用戶真正需要使用這個對象的時候,再去加載所需的js。也就是說
復制代碼 代碼如下:
Using("User"); // 這句話執行完畢之後會創建一個User對象,當時僅僅是個mock
var u = new User(); // 這個時候用需要的是真實的User對象實例,就在這個時候去動態加載JS文件,並且返回已經實例化的User對象

大家都知道,異步加載是與當前運行的狀態不沖突的,也就是說
復制代碼 代碼如下:
var u = new User();

這句話執行之後,u是一個沒有實際意義值的變量,而已。那麼,怎麼解決這個問題,我暫且想到的辦法,只能是采用同步策略了。只有當js加載完畢,再去執行之後的js語句,這個地方有點遺憾,而且同步可能帶來的浏覽器假死,也是一個比較嚴重的問題,暫且不顧這些問題,希望以後能有更好的辦法解決。

那問題出來了,這麼做同步,有什麼優勢嗎?
我不知道有什麼優勢,起碼對比異步加載,應該沒有劣勢。比如正常的異步加載為
復制代碼 代碼如下:
$.getScript("user.js",function(){
var u = new User();
});

單單執行這個語句,要執行到function,本質上也是等user.js加載完畢才會執行,那麼對比
復制代碼 代碼如下:
var u = new User();

理論上時間應該相當,因為都是等user.js加載完畢之後才執行的。

起碼第二種看起來更像java式的代碼,不必理會其他非業務相關的代碼。

那麼,怎麼會知道需要的對象在什麼地方,怎麼加載進來?我能想到的就是模擬一個配置文件,為什麼用配置文件,而不是像In.js用add函數或者其他框架的類似於register的函數,大概我只是想用配置文件,更像java,而且後期的修改起來也會更解耦一些吧。
復制代碼 代碼如下:
Using.Config = {
"User" : "/js/user" // 可以隱去.js 因為肯定是加載JS文件了
}

整個思路大概就是這個樣子,我在其基礎上進行了一些約束,比如加入了命名空間
復制代碼 代碼如下:
var u = new Using.Modules.User();

這樣可以減少一些全局變量,而且有需要的話,可以插入一些所有對象可能都具有的共性,減少創建類時的重復編碼。

當然,也還是支持不使用命名空間的。

為了解決這個約束的效力,加入了Class.create函數來進行類創建約束。
復制代碼 代碼如下:
Using.Class.create("User",function(){
}).property({
}).static({
}).namespace(Using.Modules);

這裡的大概意思就是

create(類名,構造函數)
property(類的屬性)
static(類的靜態屬性)
namespace(命名空間)

引申到此,為何不加入MVC形式?
後來我發現,要MVC,那麼幾個類之間的動態維護,或者創建之時就由Using這個類來自動維護,暫時還沒想到好的解決辦法,所以沒有加入其中,只能自己創建類,自己維護了.

通過上面的文字,最後得到一個Using.js
然後在頁面裡面就只需要引入一個
復制代碼 代碼如下:
<script type="text/javascript" src="using.js"></script>

這樣接下來就可以寫
復制代碼 代碼如下:
Using("jquery");
Using("User");

$("#ID").click(function(){
var user = new User();
user.name = "xx";
user.show();
});
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved