也說JS腳本加載控制


問題背景

  前端采用的 iframe + html 做后台管理系統。現在js、jquery插件非常多,每次頁面都是引用就類似這樣:

    <script src="../Scripts/jquery-1.7.1.js"></script>
    <script src="../Scripts/uploadify/jquery.uploadify.js"></script>
    <script src="../Scripts/uploadify/swfobject.js"></script>
    <link href="../Scripts/uploadify/uploadify.css" rel="stylesheet" />

  有時候需要更新其中一個組件,為了避免客戶端瀏覽器手動刷新,一般的做法是增加版本號,比如 xxx.js?v=1111。

      或者說,需要刪掉某個組件,引用某個組件。

      在這2種情況下,都需要針對每個頁面,增加 script 引用。每次新建一個html,就要把之前的頁面的 script 引用都復制過來,有木有?

解決辦法

  現在有Require.js , sea.js ,labjs 等等各種高大上的框架。

  以上框架中,樓主僅試過用lab.js解決這種問題,它可以很好的控制腳本的異步加載,以及腳本的依賴,然后可以在腳本加載完畢后,做初始化的操作。當時僅僅是做了一個Demo,一直過了很長時間,也沒有使用,原因無它,如果希望能控制腳本的動態加載時,又希望像以前一樣直接在頁面上引用script,換句話來說,樓主要的不是重寫腳本引用方式,而是在原有基礎上稍作改善。

     關鍵方法很簡單,使用了 document.writeIn('...') 來加載。這種加載方式,是同步加載,就是它了。

  具體思路則是,定義一個數組存放腳本以及css路徑,建議使用絕對路徑,這樣不會因為頁面所在的位置而導致腳本加載不上。

     然后做了一點點小改進,同步加載js,異步加載css。同時支持設置版本號,這樣可以輕松控制客戶端的自動更新。大致實現代碼如下:

  在實際應用過程中,這個js腳本,是會經常發生變更,所以必須再通過 document.writeIn 加載這個腳本。首先可以以如下形式寫在頁面中

<script>
document.writeIn('...');
</script>

  這樣略微不方便啦。於是樓主又寫了一個腳本,僅僅只有如上一行代碼,就是用來控制加載前面定義通用的腳本組件。這個只有一行代碼的腳本,是萬年不變的,所有頁面直接引用即可,由它來控制后面的腳本變化。

測試

  上面說,腳本加載的形式是同步的,為了證明這一點,樓主不得不寫一點簡單的例子。看看下面的html代碼:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
<body>
    <input type="text" id="uid" value="111" />
</body>
</html>
<script src="Scripts/com/boot.js"></script>
<script>
    alert($("#uid").val());
</script>

  而boot.js就是引導腳本,就是之前提到的一行代碼:

/*引導加載所有的js文件*/document.writeln("<script src='/Scripts/com/bootallscript.js?v=" + Math.random() + "'><\/script>");

  bootallscript.js就是最核心的了,復雜加載所有的js和css。

(function () {
    var base = '/Scripts/';
    var loader = {
        base: '/Scripts/',
        ver: 1,
        content: [ //定義需要加載的腳本
              'jquery-1.7.1.min.js'
        ],
        loadcss: function (cssUrl) {
            var link = document.createElement("link");
            link.rel = "stylesheet";
            link.type = "text/css";
            link.href = cssUrl;
            document.getElementsByTagName("head")[0].appendChild(link);
        },
        run: function () {
            for (var i in loader.content) {
                var c = loader.content[i];
                if (c.length <= 2) continue;
                var p = loader.base + c + "?v=" + loader.ver;;
                var type = c.substr(c.length - 2, c.length);
                if (type === 'js') { //同步加載js文件
                    document.writeln("<script src='" + p + "' ><\/script>");
                } else { //異步加載css文件
                    loader.loadcss(p);
                }
            }
        }
    };
    //加載js腳本 
    loader.run();
})();

  運行后會發現,頁面在加載完成后,使用jQuery獲取到了控件的值。這種方式和原來的直接腳本引用,差別不大吧。

  說到這里,我們新建頁面后,只需要引用 boot.js就能加載上所有的組件,而頁面邏輯相關的js,也可以直接引用在boot.js下方,沒有改變原來的腳本引用習慣,又能極大的節省了代碼,完善對腳本的控制,這就是樓主想要的效果了。  

  寫在最后,當然mvc對類似的問題有了解決方案,這里不探討,因為討論的是 前端 iframe+html 無 C# 。

  示例下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM