標籤:c style class blog code java
使用範圍:
OA、MIS、ERP等資訊管理類的項目,暫時不考慮網站。
遇到的問題:
完成一個項目,往往需要引用很多js檔案,比如jQuery.js、easyUI等。還有自己寫的一些列js檔案,那麼這些檔案如何方便的載入,如果檔案有變化如何才能讓用戶端及時更新緩衝?如果能夠提高點運行效率,那就更好了。
目標:
1、 可以方便的引用js檔案。
2、 盡量使用各種緩衝,避免頻繁從伺服器讀取檔案。
3、 如果js檔案有更新或者增加、減少幾個減少js檔案,需要用戶端能夠自動、立刻更新。
4、 Js檔案的複用。
頁面結構:
一般OA、MIS這一類的項目,大多採用frameset或者iframe的方式來實現,這樣就有了父頁和子頁的概念。我們可以利用這一點來做做文章。
網頁可以分為三塊:外殼、首頁、標籤、資料列表、表單(添加、修改)。因為這裡要說的載入js的方法,需要利用這種頁面結構,也正是因為這個原因,所以暫時不支援網站。
看這個圖有點眼熟吧。恩,就是這種結構。
本文
現在做web版的應用,越來越依賴各種js了,第三方的jQuery、easyUI、my97等,還有自己寫的各種js。要實現的功能越來越多,需要使用的js也越來越多,js檔案的修改也很頻繁。於是就出現了許多問題,比如每個頁面都要寫一大堆<script src=””>。這個也太麻煩了吧,增加一個新的js檔案,需要改多少頁面?js檔案更新了如何讓用戶端也立即更新?如何讓用戶端更快的載入js。有的Js檔案還有依賴關係,如何確保載入順序?本文內容就是分享一下我的解決方案。
動態載入
在頁面裡使用<script>載入js,顯然很麻煩,那麼怎麼辦呢?想來想去還是用動態載入的方法來解決。在網上也搜尋了一番,有很多種方法,有自己手動寫的,有整理成架構的(比如seejs)。有的時候還是感覺自己弄一個更加的應手,所以打算自己寫一套。
如何動態載入呢?使用jQuery提供的方法嗎?這個倒是可以,但是頁面必須引用jQuery和我寫的載入js檔案的js。也就是說一個頁面要寫兩個<script>,這個就麻煩了。能寫一個,就一定不要寫兩個,雖然只是多了一個,但是多了這麼一個就真的很麻煩。所以決定自己手寫一個動態載入的小方法。
不會寫怎麼辦呢?百度大嬸來幫忙吧。各種搜呀,終於找到了一個比較理想的方法,恩就用這個了。
1 /*實現動態載入js的函數,來自於互連網,做了一點修改,可以相容IE10 */ 2 var loadscript = 3 { 4 $$: function(id) { return document.getElementById(id); }, 5 tag: function(element) { return document.getElementsByTagName(element); }, 6 ce: function(element) { return document.createElement(element); }, 7 js: function(url, callback) { 8 var s = loadscript.ce(‘script‘); 9 s.type = "text/javascript";10 s.src = url;11 if (document.documentMode == 10 || document.documentMode == 9) {12 s.onerror = s.onload = loaded;13 } else {14 s.onreadystatechange = ready;15 s.onerror = s.onload = loaded;16 }17 loadscript.tag(‘head‘)[0].appendChild(s);18 19 function ready() { /*IE7.0/IE10.0*/20 if (s.readyState == ‘loaded‘ || s.readyState == ‘complete‘) {21 callback();22 }23 }24 25 function loaded() { /*chrome/IE10.0*/26 callback();27 }28 }29 };
載入順序
和新代碼已經搞定了,下面就是如何載入其他js檔案了,由於檔案比較多,還有一定的依賴關係,想來想去還是弄個js檔案的字典吧,然後做一個載入順序,按照這個順序來載入。
為了更穩定一點,決定採用一個一個載入的方式,即載入完一個js,然後在載入另一個js。這樣就可以確保依賴關係。當然缺點是載入速度會比較慢。一般網頁載入js是可以多個js檔案一起下載的,這個速度就會比較快。
使用緩衝
一般瀏覽器對於各種資源(比如網頁、圖片、js、css等)會有一個緩衝,已經有了就不會再向伺服器去下載了。看似很好,但是有兩個問題:
A、瀏覽器如何判斷緩衝的js檔案是不是最新的?
B、js檔案更新了,如何強制瀏覽器更新?
瀏覽器是怎麼判斷的呢?具體步驟我也不太清楚,只是知道有一個步驟是要到伺服器問問,我緩衝的js檔案是不是最新的,然後才能夠確定本地的緩衝是否是最新的,如果是最新的就不折騰了,如果不是再去下載最新的。就是說呢,即使用戶端已經有了js檔案的緩衝,但是瀏覽器要確認一下是否最新,還是會跑到伺服器去問問。這個,折騰呀。當然一般情況下,這個過程會很快,但是有時候這個過程會很慢。
所以呢,還是盡量避免載入js的好。於是就引出來的“js檔案的複用”。
更新js檔案
Js檔案更新了,但是瀏覽器卻還在用以前的js檔案,因為有緩衝了,而且還固執的認為緩衝的js檔案就是最新的,哎咋辦呀?
最簡單的方法就是在載入js的時候,後面跟一個版本號碼,有更新了,就版本號碼+1。比如 xxx.js?v=1。Js檔案更新後就是 xxx.js?v=2。這樣js就肯定會被更新了。
看起來似乎很簡單,但是這個版本號碼如何加上去?版本號碼本身又如何更新呢?
複用
這個就要先看看上面那個圖了,就是頁面結構,有一個外殼頁(或者首頁),我們叫做父頁。裡面還有若干個iframe載入的頁面,我們加做子頁。
一般的做法是,父頁裡載入jQuery.js,然後子頁裡也要載入jQuery.js。當然當子頁在載入jQuery.js的時候,直接從緩衝裡面提取,一般不會再去折騰伺服器了。
但是,既然父頁裡面已經載入了,子頁為啥還要再載入一次?直接用父頁裡載入好的行不行呢?到網上搜了一下,似乎沒有人這麼做。也許是我太另類了吧,我就是想實現這個方法。優點就是,所有的js檔案都在父頁裡載入,子頁直接使用父頁裡載入好的js,這樣子頁就不需要在折騰js檔案了。這樣效率也可以更高一些,畢竟即使用緩衝裡載入,也是要判斷一下,然後在做個載入的動作,還是會有一點點損耗,js檔案越多也就越明顯。
那麼如何?呢,想想似乎很簡單。
父頁裡使用jQuery
Var aa = $(’div’); //找到父頁裡的所有div
子頁裡是不是可以這麼做?
Var bb = top.$ (’div’) ; //能夠找到div,但是不是子頁的div而是父頁裡的div。
咋回事呢?原因就在於搜尋範圍。jQuery是有三個參數的,我們平時只用了第一個,後面的就被忽略了。那麼第二個參數是啥呢?就是搜尋範圍。沒有指定的時候,jQuery會在哪裡搜尋呢?載入jQuery的頁面裡面搜尋,而不是調用$的頁面裡搜尋。
解決方案也很簡單,加個參數就好了
Var bb = top.$ (’div’,document) ; //指定搜尋範圍:子頁的document
等等,這個似乎很煩人,我們在寫指令碼的時候,還要考慮一下,這個指令碼是在父頁裡執行還是在子頁裡執行嗎?
好了,做一個簡單的封裝,避免這個麻煩。子頁裡寫個函數
function $ (p1){
return top.$ (p1,document);
}
好了,大功告成了嗎?當然沒有!預知後事如何,請聽下回分解。
ps:下集預告。就是具體的實現代碼,還有一些思路和想法,不知道大家還有啥想知道的沒,有的話,歡迎在下面回複一下。謝謝先。