我有一个使用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文件中的监听器触发,一次是由侦听器触发main.built.js文件。
我希望崩溃正常运行,但我没有从WA2中删除Bootstrap.js的选项。我也没有选择在WA2中使用RequireJS。
有没有办法让WA1不用require.js加载jQuery和Bootstrap.js,但是允许通过require.js加载的模块使用jQuery和Bootstrap来正常加载(没有RequireJS)?如果没有,jQuery的$.noconflict()
可以提供帮助吗?我并不熟悉它是如何运作的。
答案 0 :(得分:3)
我最终做了以下事情:
在我加载任何require模块(包括jQuery)之前,我检查jQuery是否已经存在(如果我在WA2中运行它确实存在)。如果有,我将$isloaded
设置为true
。
加载了require bootstrap.js后,如果$isloaded
为true
,我设置$.fn.collapse = function(){}
。
这样,只有WA2加载的jquery / bootstrap中的$ .fn.collapse函数才能执行某些操作。感觉有点hacky,但它确实有效。
答案 1 :(得分:1)
这是一种做我理解你想做的事情的方法。 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开始加载任何东西之前,它被加载两次。
要件:
这必须在您最初的require.config
电话之后,但在您开始加载任何内容之前显示。
在此代码运行之前,必须已加载为WA2加载的jQuery和Bootstrap。
工作原理:
它通过检查是否已设置$
来检测是否加载了jQuery。
通过检查$.fn.popover
是否存在来检测是否加载了Bootstrap。我不知道检查Bootstrap是否已加载的制裁方法。我检查了代码并没有看到$.fn.bootstrap
或类似的任何可能是Bootstrap独有的东西。它确实设置了popover
方法,这就是我使用的方法。
如果检测到这些内容已经存在,则会填充“*”的地图,以便在需要加jquery
jquery-fake
时加载bootstrap
,同样加载{{1}}
这两个假模块是您在代码早期定义的模块。它们实际上并没有加载任何东西。
答案 2 :(得分:0)
我过去也遇到过类似的问题。直到今天我才遇到它让我很烦,但我很高兴知道我并不是唯一的一个。
我解决这个问题的方式,正如您所确定的那样,使用$.noConflict(true)
。
您需要两个require配置脚本。
对于WA1,您需要以正常方式配置require。这使您可以将其作为独立的Web应用程序运行,独立于WA2:
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
来应用类似的模式请告诉我你是怎么过的。