6

假设我想将 jquery 与已使用标准闭包定义的标准、非 amd 启用 jquery 插件一起使用:(function($))( $.fn.myplugin = { ... } )(jQuery);它都位于js/libs/jquery/jquery.myplugin.js.

我使用这个配置:

require.config({
  baseUrl: 'js/',
  paths: {
    'jquery':          'libs/jquery/jquery-noconflict', 
    'underscore':      'libs/underscore/underscore',
    'backbone':        'libs/backbone/backbone',
    'jquery-myplugin': 'libs/jquery/jquery.myplugin'
  },
  shim: {
    'backbone': {
      deps: ['underscore', 'jquery'],
      exports: 'Backbone'
  },
  'jquery-myplugin': {
    deps:  ['jquery'] 
  }
});

我在 中以无冲突模式加载 jQuery,libs/jquery/jquery-noconflict.js因为我不想污染全局命名空间:

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

这就是我加载主 app.js 的方式:

define([
  'jquery',
  'underscore',
  'backbone',
  'jquery-myplugin'],
function($, _, Backbone, MyPlugin){
  //MyPlugin is always undefined, not even sure if 
  //I should be passing it here if it only extends jQuery?
});

现在,这是我遇到的问题 - 虽然我可以毫无问题地使用上面定义的所有库,但我无法制定正确的shim配置来加载非 AMD 启用的 jquery 插件。

jquery-myplugin我已经尝试过设置depsjquery和其他方式),但我永远无法让它工作。

似乎我在以下情况下遇到问题:

  1. jQuery 以无冲突模式加载。
  2. 插件代码运行,扩展了上面 jQuery 的实例
  3. 我可以在我的应用程序中使用由插件代码扩展的 $,因此 $.myplugin 可用。

我看到过类似的问题,但没有一个真正解决了这个问题,只给出了模糊的建议,例如“使用 shim config”......

编辑

我也尝试过使用

"jquery-myplugin": {
    deps: ["jquery"],
    exports: "jQuery.fn.myplugin"
}

虽然插件方法一旦以这种方式加载为 AMD 模块就可用,但我仍然无法访问:$('.class').myplugin()因为默认 $ 对象尚未使用 myplugin 代码进行扩展。

4

3 回答 3

3

使用jQuery.noConflict(true)删除jQuery全局变量。当您的插件加载时,它会尝试访问jQuery,但不能,导致此失败。

如果您的插件是一个模块,它可以作为依赖项访问 jQuery。或者,您可以将jQuery其作为全球可用。

于 2013-01-11T18:30:40.457 回答
-1

我今天遇到了和你一样的问题。这是我可以解决的方法:

requirejs.config({
    "baseUrl": "js/lib",
    "paths": {
      "app": "../app"
    }
});

// Final version of jQuery with all needed plugins.
define("jquery", ["jquery-core", "myplugin"], function(jqCore) {
    return jqCore;
});

// Define core jQuery module.
define("jquery-core", ["jquery-1.9.1.min"], function() {
    return jQuery.noConflict(true);
});

// This module exposes jquery module to the global scope and returns previous defined version.
define("jq-global", ["jquery-core"], function(jqCore) {
    var tmp = jQuery;
    jQuery = jqCore;
    return tmp;
});

// Define your plugin here, and don't forget to reset previous jQuery version.
define("myplugin", ["jq-global", "jquery.myplugin"], function(jqGlobal, jqPlugin) {
    jQuery = jqGlobal;
});

// Load the main app module to start the app
requirejs(["app/main"]);

现在在我的 app/main.js 文件中,我可以执行以下操作:

define(["jquery"], function($) {
    $('body').myplugin();
});

这里的想法是在执行插件代码之前临时公开 jQuery。到目前为止,我还没有在更大的环境中测试解决方案,需要加载更多的模块,所以我不能保证它会长期工作;)

编辑

这个解决方案行不通!!由于 requirejs 不会按顺序加载脚本,因此插件 js 文件可能会在 jquery 之前加载,这将导致执行失败。非常遗憾。

如果有人有其他想法...

于 2013-05-10T15:16:08.840 回答
-1

首先,确保“path/to/jquery-myplugin”实际上扩展window.jQuery而不是$

noConflict() 保留window.jQuery定义的对象,但解除自身绑定window.$在某些新浏览器window.$上内置了本机document.querySelectorAll函数的别名。

其次,您的 myplugin 不需要返回自身,因为它不能单独使用。因为它扩展了jQuery,所以从 myplugin 调用返回 jQuery。

最后,“path/to/jquery-myplugin”不是一个模块。这是一个普通的 JS 文件。有可能 RequireJS 尝试像模块一样加载它并且找不到define()调用,这会导致混乱。尝试将“.js”文件扩展名添加到引用中,以向 RequireJS 发出它需要使用“js!”的信号。加载资源的插件。

require.config({
    paths: {
        "jquery": "path/to/jquery",
        "jquery-myplugin": "path/to/jquery-myplugin.js"
    },
    shim: {
        "jquery": {
          init: function() {
             return window.jQuery.noConflict();
          },
        "jquery-myplugin": {
          deps: ['jquery']
          init: function($) {
             return $;
          },
       }
    } 
});
于 2013-01-12T20:42:43.817 回答