簡體   English   中英

如何作為一個原子操作從另一個加載一個JavaScript文件,然后運行一些代碼

[英]How to load one JavaScript file from another, and then run some code, as a single atomic operation

簡短的版本:“如何在JavaScript中合成#include語句?”

長版:

我有一個JavaScript代碼文件,我希望能夠將其添加到常規網頁中,而不必在這些頁面上施加任何特定條件,而不僅僅是它們必須包含<script>標記才能加載我的文件。

我的文件包含依賴jQuery的代碼,因此我需要從我的文件中加載jQuery。 我是通過將<script>標記插入DOM來實現的。 問題是我需要立即運行一些代碼以加載jQuery,這樣我就可以確保,如果頁面上已經加載了舊版本的jQuery,它不會被新加載的jQuery覆蓋(即,我正在引用$ ,然后調用jQuery.noConflict(true); )。

為了實現這一目標,我向動態插入的<script>元素添加了onload / onreadystatechange處理函數。 這基本上是可行的, 但是問題是,如果基礎頁面在頁面准備就緒時有任何等待(即$.ready(...) ),則此代碼將在<script>元素本身的處理程序之前運行,因此由於代碼運行的是我新加載的jQuery版本,而不是頁面加載的原始版本和代碼期望的版本,因此事情發生了變化。

  var script = document.createElement("script");
  script.src = "//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js";
  script.type = "text/javascript";
  script.onload = script.onreadystatechange = function() {
    if (this.readyState && this.readyState != "loaded" &&
      this.readyState != "complete")
      return;
    var $ = jQuery;
    jQuery.noConflict(true);
    do_my_stuff($);
  }
  document.getElementsByTagName("body")[0].appendChild(script);

請注意,我無法控制從中調用代碼的網頁,因此“使頁面加載正確版本的jQuery”不是解決方案。 另外,僅將jQuery插入我的代碼文件中並不是一個很好的解決方案,因為jQuery相當大(僅使用必要的功能對其進行重新構建仍然會導致文件很大)。

您將包括覆蓋某些全局腳本(即jQuery / $ )的腳本。 通常認為這很草率,您正在體驗為什么。

一個簡單的解決方案是將jQuery修改為使用另一個命名空間,例如$my_version_of_jquery 即。 避免名稱沖突。

一個更復雜的解決方案可以通過適當的依賴注入來完成某些工作,但這對於您的用例而言可能太復雜了。


凌亂:

var my_framework = {};
my_function () {
    my_framework.some_function();
}

依賴注入:

manager.add_dependency("my_framework", function () {
    return {};
});
manager.run_with_dependencies(
  [ "my_framework", "some_other_dependency" ], // list of dependencies
  function my_function(my_framework, some_other_dependency) { // instances of dependencies
      my_framework.some_function();
  }
});

如果需要的話,這將允許您加載同一框架的兩個版本。

在研究了jQuery.getScript()工作方式之后,看來最好的解決方案是使用XMLHTTPRequest將所需的腳本加載到字符串中,然后簡單地對其進行eval()

如果我正確理解了您的查詢,則滿足以下條件:

  • 確保在執行您自己的JavaScript代碼之前加載了jQuery
  • 由於只需要一個腳本依賴項,因此必須異步加載jQuery
  • 如果已經加載了jQuery版本,請不要覆蓋全局引用

最簡單的解決方案是運行初始測試,以查看全局范圍內是否存在全局jQuery對象:

if ( !window.jQuery ) {
    // jQuery isn't there, so load your jQuery version asynchronously
} else {
    // jQuery is already there, so use the existing version
}

為了使現有解決方案正常工作,您需要使用其他全局引用。 因此,您可以使用var $myJq = jQuery.noConflict()代替var $ = jQuery 注意:傳遞true將從全局范圍中刪除任何現有的jQuery引用。

加載兩個單獨的版本並不是很有效,因此,如果可以的話,我建議使用上述條件來決定要做什么。 但是,如果版本對於您自己的代碼很重要,則第二個解決方案應該可以。

暫無
暫無

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

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