js的動態加載、緩存、更新以及複用(一)

 

使用範圍:

  OA、MIS、ERP等信息管理類的項目,暫時不考慮網站。javascript

 

遇到的問題:

  完成一個項目,每每須要引用不少js文件,好比jQuery.js、easyUI等。還有本身寫的一些列js文件,那麼這些文件如何方便的加載,若是文件有變化如何才能讓客戶端及時更新緩存?若是可以提升點運行效率,那就更好了。css

 

目標:

一、  能夠方便的引用js文件。java

二、  儘可能使用各類緩存,避免頻繁從服務器讀取文件。web

三、  若是js文件有更新或者增長、減小几個減小js文件,須要客戶端可以自動、馬上更新。chrome

四、  Js文件的複用。瀏覽器

 

頁面結構:

 

  通常OA、MIS這一類的項目,大多采用frameset或者iframe的方式來實現,這樣就有了父頁和子頁的概念。咱們能夠利用這一點來作作文章。緩存

 

  網頁能夠分爲三塊:外殼、首頁、標籤、數據列表、表單(添加、修改)。由於這裏要說的加載js的方法,須要利用這種頁面結構,也正是由於這個緣由,因此暫時不支持網站。服務器

 

  看這個圖有點眼熟吧。恩,就是這種結構。app

  

正文

  如今作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:下集預告。就是具體的實現代碼,還有一些思路和想法,不知道你們還有啥想知道的沒,有的話,歡迎在下面回覆一下。謝謝先。

 

相關文章
相關標籤/搜索