2012-03-19 87 views
1

我寫這取決於我想要有條件包括外部庫插件,也就是說,用戶可以選擇不在情況下,用戶的網站已經擁有了它們被自動包含那些圖書館。下面是一些僞代碼來說明問題有條件地加載外部JavaScript庫在我的插件

<script type="text/javascript" src="path/to/plugin.js"></script> 
<script type="text/javascript"> 
PLUGIN.init({ 
    "param1": "foo", 
    "parma2": 33, 
    "include": {"jquery": 0, "googlemaps": 0} 
}); 
</script> 

在我的插件腳本

var PLUGIN = { 
    "init": function(obj) { 
     if (obj.include.googlemaps !== 0) { 
      document.write('<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true&v=3.6">\x3C/script>'); 
     } 

     if (obj.include.jquery !== 0) { 
      document.write('<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js">\x3C/script>'); 
     } 

     .. do more things .. 
} 

的問題是,當我準備「做更多的事情,」似乎是庫沒有被加載然而。我得到一個錯誤,沒有找到jquery,或找不到谷歌地圖。我可以通過更改我的代碼來解決此問題

document.write('<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true&v=3.6">\x3C/script>'); 
document.write('<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js">\x3C/script>'); 

var PLUGIN = { 
    "init": function(obj) {   
     .. do more things .. 
} 

但現在用戶無法控制加載庫或不加載它們。建議?解決方法?

更新:感謝您的建議,你們所有人,但目前爲止沒有喜悅。這就是我在做什麼,發生了什麼。因爲我可能加載0或多個腳本(用戶可以選擇決定哪些腳本不需要加載),我做了我的代碼,像這樣

"importLib": function(libPath, callback) { 
    var newLib = document.createElement("script"); 

    if (callback !== null) { 
     newLib.onload = callback; 
    } 
    newLib.src = libPath; 

    document.head.appendChild(newLib); 
}, 

"init": function(obj) { 
    var scripts = []; 
    if (obj.include.googlemaps !== 0) { 
     scripts.push("http://maps.google.com/maps/api/js?sensor=true&v=3.6"); 
    } 

    if (obj.include.jquery !== 0) { 
     scripts.push("http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"); 
    } 

    if (obj.include.anotherlib !== 0) { 
     scripts.push("http://path/to/another/lib.js"); 
    } 

    var len_scripts = scripts.length, 
     callback = null; 

    if (len_scripts > 0) { 
     for (var i = 0; i < len_scripts; i++) { 

      // add callback only on the last lib to be loaded 
      if (i == len_scripts - 1) { 
       callback = function() { startApp(obj) }; 
      } 

      importLib(scripts[i], callback); 
     } 
    } 

    // Start the app rightaway if no scripts need to be loaded 
    else { 
     startApp(obj); 
    } 
}, 

"startApp": function(obj) { 
} 

什麼情況是,火狐與attempt to run compile-and-go script on a cleared scope錯誤嘎嘎叫着,和Safari不會收到該錯誤,但不會加載任何內容。有趣的是,Safari錯誤控制檯根本沒有顯示任何錯誤。好像Firefox的錯誤是,如果我的評論,錯誤消失行document.head.appendChild(newLib);造成的,但當然,網頁無法正確加載。

+0

首先,設置你在列表中的最後一個庫的回調不是你想要的:如果第一個庫來自一個非常慢的服務器會怎麼樣?在回調已經觸發後,它可能會在最後列出的腳本之後加載數秒。您應該使用計數器來計算所請求的庫的數量。每次加載一個lib時,觸發一個回調,即1)遞減計數器,2)如果計數器下降到0,則啓動應用程序。 – apsillers 2012-03-20 12:36:38

+0

其次,嘗試搜索該錯誤文本。它看起來像清理緩存將修復它。 – apsillers 2012-03-20 12:39:18

回答

1

你應該添加的每個腳本作爲一個DOM節點,並使用onload屬性時,它已經完成加載採取行動。

function importLib(libPath, callback) { 
    var newLib = document.createElement("script"); 
    newLib.onload = callback; 
    newLib.src = libPath; 
    document.head.appendChild(newLib); 
} 

上面,libPath參數是庫的URL,以及callback說法是加載完成時調用的函數。

importLib("http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js", function() { 
    alert("jquery loaded!"); 
    nowDoSomething(aboutIt); 
}); 

順便說一句:你可以按如下方式使用它在一般情況下,document.write是不是大多數問題的一個很好的解決方案(但我不會說從未正確的解決方案 - 有例外的每規則)。

+0

請參閱原始文章的更新(因爲註釋中不允許格式化) – punkish 2012-03-19 23:05:56

0

上述解決方案將在現代瀏覽器的工作,但對於IE 7/8ü可能想添加一些額外的代碼,這樣的事情:

function importLib(libPath, callback) { 
    var newLib = document.createElement("script"); 
    if (navigator.userAgent.indexOf('MSIE') !== -1) { 
     newLib.onreadystatechange = function() {// this piece is for IE 7 and 8 
      if (this.readyState == 'complete') { 
       callback(); 
      } 
     }; 
    } else { 
     newLib.onload = callback; 
    } 
    newLib.src = libPath; 
    document.head.appendChild(newLib); 
} 
0

我遇到了同樣的問題。一個解決辦法,如果你在使用.NET編寫你的網站是通過有條件地寫從後面的代碼加載頁面之前,腳本參考。我的問題是,當遠程用戶通過VPN訪問我的應用程序,它會阻止訪問互聯網,因此谷歌的地圖不能被引用。這可以防止在合理的時間內加載頁面的其餘部分。我試圖通過控制jQuery的getScript加入谷歌地圖庫的腳本引用()命令,但是你發現,外部庫引用之前隨後的谷歌地圖的配置代碼運行。

我的解決辦法是有條件地引用谷歌地圖從後面的代碼代替:

VB(代碼後面):

'if VPN mode is not enable, add the external google maps script reference (this speeds up the interface when using VPN significantly) 
    If Session("VPNMode") = False Then 
     Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder() 
     sb.AppendLine("") 
     sb.AppendLine("<script type='text/javascript'") 
     sb.Append(" src='http://maps.google.com/maps/api/js?v=3&sensor=false'>") 
     sb.Append("</script>") 

     Dim header As LiteralControl = New LiteralControl 
     header.Text = sb.ToString() 
     Me.Page.Header.Controls.Add(header) 
    End If 

客戶端側腳本(JavaScript的):

<script type='text/javascript'> 
    $(function() { 

     if ($("input[name*='VPN']").is(":checked")) 
     { } 

     else { 
      loadGoogleMap() 
     } 
    }); 
    function loadGoogleMap() { 

     hazsite = new google.maps.LatLng(hazLat, hazLong); 
     map = new google.maps.Map(document.getElementById('map_canvas'), { zoom: 18, center: hazsite, mapTypeId: google.maps.MapTypeId.SATELLITE }); 
     var marker = new google.maps.Marker({ 
      position: hazsite, 
      map: map, 
      title: "Site Location" 
     }); 
    } 
</script>