【问题标题】:Bootstrap Collapse conflicts with multiple jquery and bootstrap.js; require.jsBootstrap Collapse 与多个 jquery 和 bootstrap.js 冲突;需要.js
【发布时间】:2014-05-21 21:01:23
【问题描述】:

我有一个使用 RequireJS 加载 jQuery 和 Bootstrap.js 的 Web 应用程序(我们称之为 WA1)。此应用程序被构建到单个文件 (main.built.js) 中,并在不同 Web 应用程序 (WA2) 上的页面元素内运行。

(WA1 也可以独立运行——无需内置到 WA2 中)

WA2 正常加载 jQuery 和 Bootstrap.js,但 main.built.js 文件中还包含 jQuery 和 Bootstrap.js。

WA1 的部分 UI 包含一个 Bootstrap 折叠元素。折叠/展开的动作由 html 中的数据属性触发。如果您查看this fiddle,应该折叠的元素不能折叠——我认为因为折叠动作被触发了两次——一次由 WA2 Bootstrap.js 文件中的侦听器触发,一次由主文件中的侦听器触发.built.js 文件。

我希望折叠功能正常运行,但我无法从 WA2 中删除 Bootstrap.js。我也没有在 WA2 中使用 RequireJS 的选项。

有没有办法让 WA1 不使用 require.js 加载 jQuery 和 Bootstrap.js,但允许通过 require.js 加载的模块使用正常加载的 jQuery 和 Bootstrap(没有 RequireJS)?如果没有,jQuery 的 $.noconflict() 可以提供帮助吗?我不太熟悉它的工作原理。

【问题讨论】:

    标签: jquery twitter-bootstrap requirejs amd


    【解决方案1】:

    我最终做了以下事情:

    • 在我加载任何 require 模块(包括 jQuery)之前,我会检查 jQuery 是否已经存在(如果我在 WA2 中运行,它确实存在)。如果这样做,我将$isloaded 设置为true。

    • require bootstrap.js加载后,如果$isloaded是true,我设置$.fn.collapse = function(){}。

    这样,只有 WA2 加载的 jquery/bootstrap 中的 $.fn.collapse 函数会起作用。感觉有点 hacky,但它确实有效。

    小提琴:http://jsfiddle.net/wSPXP/17/

    【讨论】:

      【解决方案2】:

      这是我理解您想做的事情的一种方法。 console.log 语句只是用来检查发生了什么。如果我在您的小提琴中的require 调用之前(以及在require.config 调用之后)添加以下代码段,那么折叠元素可以正常工作:

      (function () {
          define("jquery-fake", [], function () { 
              console.log("jquery-fake"); 
              // Just return the already loaded jQuery.
              return $; 
          });
      
          define("bootstrap-fake", ["jquery"], function () { 
              console.log("bootstrap-fake");
              // Nothing to be done here.
          });
      
          var map = {};
      
          if ($)
              map.jquery = "jquery-fake";
      
          if ($.fn.popover)
              map.bootstrap = "bootstrap-fake";
      
          require.config({ map: { "*": map } });
      })();
      

      如果您不也从“外部资源”列表中删除 jQuery,上述方法将不起作用。现在,它被加载了两次之前RequireJS 开始加载任何东西。

      要求:

      1. 这必须出现在您最初的 require.config 调用之后,但在您开始加载任何内容之前。

      2. 为 WA2 加载的 jQuery 和 Bootstrap 必须已经在此代码运行之前加载。

      它是如何工作的:

      1. 通过检查是否设置了$来检测jQuery是否加载。

      2. 通过检查$.fn.popover是否存在来检测是否加载了Bootstrap。我不知道检查 Bootstrap 是否已加载的认可方法。我检查了代码,没有看到 $.fn.bootstrap 或任何类似的东西,这可能是 Bootstrap 独有的。它确实设置了一个popover 方法,所以这就是我使用的方法。

      3. 当检测到这些已经存在时,会填充“*”的映射,以便在需要 jquery 时加载 jquery-fake,同样地加载 bootstrap。

      4. 这两个假模块是您在代码早期定义的模块。它们实际上并没有加载任何东西。

      Fiddle

      【讨论】:

      • 你能和这个工作分享一个 jsfiddle 吗?我将您的剪辑添加到我的小提琴中,但折叠元素仍然无法正常工作。
      • 终于可以自己实现这个模式了!更好的方法,干得好+1
      【解决方案3】:

      我过去也遇到过类似的问题。直到今天我都遇到了它,这让我很恼火,但我很高兴知道我不是唯一一个。

      我的解决方法是,正如你所确定的那样,使用$.noConflict(true)。

      您将需要两个需要配置脚本。

      对于 WA1,您需要以正常方式配置 require。这将使您能够将其作为独立于 WA2 的独立 Web 应用程序运行:

      require.config({
          paths: {
              'jquery': '//code.jquery.com/jquery-1.11.0.min.js',
              //...
          }
      });
      

      对于 WA2,您需要像这样配置 require:

      require.config({
          paths: {
              'jquery': 'src/jquery-no-conflict',
              'jquery-src': '//code.jquery.com/jquery-1.11.0.min.js',
              //...
          }
      });
      

      在 jquery-no-conflict.js 中,我们加载了 jQuery,但是将全局 $ 恢复为 WA2 加载的版本:

      define(['jquery-src'], function ($) {
      
          //unload the newly loaded version of jQuery
          $.noConflict(true);
      
          //return the original version
          return $;
      });
      

      现在,当从 WA2 加载时,您在 WA1 中的 define 函数将调用 jquery-no-conflict.js

      我唯一不喜欢这种模式的是你的 WA1 的 HTML 现在包含两个对 jQuery 的引用,尽管全局 $ 仍将指向加载的第一个 jQuery 实例。

      虽然我没试过,想必你可以使用Bootstrap的noConflict应用类似的模式

      请告诉我你的进展如何。

      【讨论】:

      • 如果我在我的模块中调用 bootstrap.js 函数,这是一个很好的解决方法,但我认为问题是单击具有 data-toggle 属性的元素仍然会触发两个 jQuery,因为触发器来自 DOM 中的点击事件,而不是我的模块之一。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-06
      • 1970-01-01
      • 1970-01-01
      • 2017-07-27
      • 2014-04-12
      • 2014-03-02
      相关资源
      最近更新 更多