javascript - jQuery noconflict、bootstrap 和 requirejs

标签 javascript jquery twitter-bootstrap requirejs

我正在开发的环境使用的是 jQuery 1.7.1,而我需要专门使用 jQuery 2.1.3。但是当我使用 2.1.3 时,一些遗留代码中断(因为它使用 1.7.1)所以我不得不在 2.1.3 上使用 jQuery.noconflict

jquery-private.js:

define(["jquery"], function(jQuery){
    return jQuery.noConflict(true);
});

然后在我的 requirejs 配置文件中我有这个:

配置文件:

requirejs.config({
    baseUrl: '../',
    paths: {
        'jquery': 'js/jquery/jquery',
        'jqueryui': 'js/jquery-ui/jquery-ui',
        'bootstrap': 'js/bootstrap',
    },
    map: {
        // '*' means all modules will get 'jquery-private'
        // for their 'jquery' dependency.
        '*': {
            'jquery': 'jquery-private'
        },

        // 'jquery-private' wants the real jQuery module
        // though. If this line was not here, there would
        // be an unresolvable cyclic dependency.
        'jquery-private': {
            'jquery': 'jquery'
        }
    },
    shim: {
        'bootstrap': {
            deps: ['jquery']
        }
    }
});

那么当我需要 Bootstrap 时

小部件.js:

require([
    "jquery",
    "bootstrap"
], function(jqr){
    // SOME CODE
});

我得到一个错误:

Uncaught Error :Bootstrap 的 JavaScript 需要 jQuery 1.9.1 或更高版本

所以 bootstrap 正在使用 1.7.1。

如何在不更改 bootstrap.js 文件的情况下让它获取 2.1.3?

最佳答案

为什么会失败?

您当前的尝试无法工作,因为您的 jquery-private 设置确保一旦 jQuery 作为 RequireJS 模块加载,noConflict() 就会被调用。只要用 RequireJS 加载的代码通过 define 调用引用 jQuery(例如 define(['jquery'], function ($) {) 就没有问题. 但是,填充的任何代码都将引用 $jQuery 全局变量,因此将引用版本 1.7.1。

解决方案

没有任何其他约束,首选解决方案是让整个代码库使用相同的 jQuery 版本。将 1.7.1 升级到 1.x 系列的最新版本,然后使用它。根据download page , 2.x 和 1.x 系列中相对较新的版本(我会说 1.9.x 及更高版本)之间没有 API 差异。当然,这意味着依赖于 1.7.1 的代码可能必须更新才能与 1.x 系列中最新的 jQuery 一起工作。

我建议升级到 2.x 系列,但您在评论中提到需要与 IE 6 和 7 兼容。请注意:如果您设法为同一页面加载 1.7.1 和 2.1.3,使用 2.1.3 的那部分代码不会与 IE 6 和 7 兼容,因此该页面实际上不再与 IE 6 和 7 兼容。

要使用此解决方案,除了必须为升级所做的更改外,您还必须:

  1. 确保 jQuery 在之前加载 RequireJS。否则,它会检测 RequireJS 并调用 define 但随后它不会可靠地可用于未加载 RequireJS 的代码。 (我说过它不会“可靠地可用”,因为尽管一旦加载了 jquery 模块,jQuery$ 全局变量就会存在,问题是没有加载 RequireJS 的代码无法等待 RequireJS 加载 jQuery。因此,除非您煞费苦心地编写自己的同步代码,否则它不会可靠地工作。)

  2. 创建一个 RequireJS 模块,它仅使在 RequireJS 模块之前加载的 jQuery 作为一个模块可用于 RequireJS 模块,因此:

    define('jquery', function () { return jQuery; });
    

    这可以放在调用 require.config 之前。这会创建一个“假”jquery 模块,它只返回全局 jQuery 符号。 (它也可以返回 $。)

备选方案?

我看不到上述解决方案的稳健替代方案。提出可以证明另一种方法的概念证明并不难。但是,一旦您尝试在实际项目中使用它,它就会失败。问题是 RequireJS 本质上是异步的,所以你不能开始弄乱 $jQuery 全局变量来按照你想要的方式设置它们并确保你想要的一切发生会在您希望它发生的时候发生。此外,在 RequireJS 之前加载的任何代码恰好启动异步操作,而异步操作可能与 RequireJS 的模块加载交错发生,这会给整个操作带来麻烦。我宁愿避免提出一旦从概念验证到实际应用就会失败的解决方案。

关于javascript - jQuery noconflict、bootstrap 和 requirejs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31020525/

相关文章:

javascript - jScrollPane 不适用于 meteor.js

javascript - 除了 Select 之外,如何更改 ngFor 中组件的响应,并使其他组件保持可见?

javascript - GZipping CSS 和 JS 文件

twitter-bootstrap - Bootstrap : Navbar Logo Size

javascript - 从 Javascript 动态生成时,日期时间选择器不会弹出

javascript - C# 字符串到 Javascript var

javascript - 在 Rails 中通过轮询刷新多个部分

php - 在文本区域中输入数字或字符时如何减少计数

javascript - 选择具有共同 Id 的各种不同的类

html - 侧边栏正在延伸过去的视口(viewport)