簡體   English   中英

加載第二個版本的jQuery和其他庫

[英]Loading a second version of jQuery, and other libraries along with it

我正在制作一個由一段代碼組成的小部件,該代碼段可放入您的網站,然后通過js提取內容。 這是一個示例片段:

<div data-token="bc1cea6304e8" id="my-widget">
    <script src="http://localhost:8080/assets/eg-widget.js" type="text/javascript"></script>
</div>

我正在做一個測試,以檢查頁面是否已經有jQuery,如果是,則該版本至少為1.5。

if (typeof jQuery == 'undefined' || isVersion("1.5", ">")) {

    var script_tag = document.createElement('script');
    script_tag.setAttribute("type", "text/javascript");
    script_tag.setAttribute("src",
        "http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js");

    // Try to find the head, otherwise default to the documentElement
    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);

    if (script_tag.readyState) {
        script_tag.onreadystatechange = function () { // For old versions of IE
            if (this.readyState == 'complete' || this.readyState == 'loaded') {
                scriptLoadHandler();
            }
        };
    } else { // Other browsers
        script_tag.onload = scriptLoadHandler;
    }
} else {
    // The jQuery version on the window is the one we want to use
    jQueryEg = window.jQuery;
    scriptLoadHandler();
}

無論哪種情況,我們都將變量jQueryEg設置為我們決定使用的jQuery,以便避免沖突。

如果尚未加載jQuery,則一切正常。 但是,如果加載了舊版本,則在嘗試加載其他庫(如jQuery-ui)時會發生沖突。

為此,我們將window.jQuery設置為新加載的jQuery,以便在加載jquery-ui和bootstrap.js時,它們對window.jQuery或$的引用指向正確的版本。

問題在於,有時在我們將window.jQuery設置為我們的版本的同時,頁面的其他部分正在調用jQuery,這會導致問題。

關於如何避免這些沖突的任何想法?

jQueryEg = window.jQuery.noConflict(true);
window.jQueryEg = jQueryEg;

// jquery-ui reference window.jQuery so we need to set that to our new jquery for a sec

if (jQueryEg.ui == undefined || jQueryEg.ui.datepicker == undefined) {
    var otherjQuery = window.jQuery;
    window.jQuery = jQueryEg;

    var script_tag = document.createElement('script');
    script_tag.setAttribute("type", "text/javascript");
    script_tag.setAttribute("src",
        "//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js");
    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);

    script_tag.onload = function () {
        window.jQuery = otherjQuery;
        main();
    };

}

有一次我遇到類似的問題 在查看jQuery-UI代碼時,我注意到它們全部包裝在立即調用的函數表達式中(或者我自己包裝了它?我不記得了):

( function ( jQuery, undefined ){
  // Code here...
})( jQuery );

創建私人范圍 所以我的解決辦法是

  1. 將當前的jQuery保存到jQuery_OLD
  2. 加載新的jQuery版本
  3. 加載jQuery-UI,並使其獲取兼容版本
  4. 恢復舊的jQuery

所以下面給出了這個想法

<script src="jquery-1.4.js"></script>
<script>
    var jQuery_1_4 = jQuery.noConflict();
</script>
<script src="jquery-1.8.js"> </script>
<!-- load jquery UI -->
<script src="jquery-ui.js"> </script>
<!-- restore window.jQuery -->
<script>
    jQuery = jQuery_1_4;
</script>

之前遇到過這種確切的情況,最終確定是您可能已經知道的,並且不想聽到:加載這樣的外部庫的多個版本時,根本沒有避免所有邊緣情況的好方法,由於您已經指定的原因。 所涉及並發症的摘要是:

  • 當然,主要的問題是:外部腳本的加載本質上是異步的,並且沒有“執行前” /“執行后”回調以確保所有內容都被包裝好。 即:沒有辦法“包圍”動態加載的代碼。
  • 將腳本直接放置在文檔中時會按順序執行腳本,但是無法根據另一個腳本確定的條件來有條件地加載一個腳本。
  • 最后,出於用戶友好的原因(即:允許網絡上的隨機人員使用零代碼知識且無需支持人員的情況下使用您的代碼段),例如“確保所有其他腳本之前粘貼此代碼段!”這樣的限制! 馬上出來。 即使它們可以工作(*並且他們不會,實際上看不到其他兩點),它們也會被忽略,尤其是那些對頁面沒有完全控制權的人。

不幸的是,唯一的答案是顯而易見的:在自己的服務器上托管庫的修改版本。

當然,您不需要一直提供這些版本,因此您仍然可以受益於Google CDN的使用。 同時,您仍然可以使用自己的CDN交付修改后的版本。 要遵循的主要准則是:

  1. 加載整個頁面后(使用onDOMReady等)運行腳本,以確保在包含您自己的腳本之后“不會”發生沖突。
  2. 確定是否可能發生沖突。 在這種情況下,請提供修改后的版本,否則,可以通過公共CDN提供服務。
  3. 經常檢查與其他庫的兼容性。 您的代碼將隨着時間的推移而發展,就像您使用的庫一樣。 “確定是否可能發生沖突”步驟必須准確才能起作用。 謹慎一點,請注意:如果不確定,請提供您自己的版本。
  4. 始終為粘貼程序提供一個簡單的選項,讓其說“始終使用修改后的版本”,以防檢測失敗。
  5. 始終提供壓縮的丑陋的腳本版本以及適當的緩存頭 ,以減少您自己的服務器上的負載。

通常,您通常會發現,相對而言,您自己的服務器上的匹配次數實際上很少。 與往常一樣,不要相信我:在您自己的真實場景中保存統計信息!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM