在YUI中加载jQuery和插件

我试图加载jQuery作为YUI模块,而不是将其添加到全局范围。

我想出的最好的方法是创建一个全局的module.exports以便jQuery认为它是一个通用的js模式,并且不会创建一个全局的jQuery对象……

 // must create global object for jQuery to detect and attach to // otherwise it will create itself in the global scope module = { exports: {} }; YUI({ modules: { 'my-jquery': { fullpath: '//cdnjs.cloudflare.com/ajax/libs/jquery/1.10.1/jquery.min.js', requires: [ 'node'] } }, onProgress: function (e) { switch (e.name) { case 'my-jquery': (function () { var clone; YUI.add('my-jquery', function (Y) { if (!clone) { clone = Y.clone(module.exports, true); module.exports = {}; } Y.namespace('my').jQuery = clone; }, '1.10.1', { requires: [ 'node'] }); })(); break; } } }).use('my-jquery', function (Y) { console.log('before'); var jQuery = $ = Y.my.jQuery; console.log('walks'); // regular old jQuery stuff here... $('#main').hide(); // no global jQuery object console.log(1, window.jQuery); // there is a local jQuery object console.log(2, jQuery); }) 

演示: http : //jsfiddle.net/syvGZ/2/

有没有更好的方法在YUI中加载jQuery而不涉及全局范围?

使用onProgress ,你在正确的轨道上,但你不需要跳过克隆和伪造module.exports所有module.exports 。 诀窍是使用jQuery.noConflict()

jQuery.noConflict做了两件事:

  • 它返回jQuery函数
  • 如果它存在,它将恢复以前版本的jQuery,或者从全局对象中删除jQuery

以下是其工作原理的说明:

     

另一个问题是,由于YUI期望脚本具有连接模块,因此e.name不引用模块的名称,而是引用刚刚加载的脚本的URL。 可以在e.data中的数组中找到该脚本中加载的模块的名称。 这只是意味着您需要迭代e.data以确定是否加载了jQuery。

总结一下,你的脚本应如下所示:

 YUI({ modules: { 'jquery': { fullpath: '//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js' } }, onProgress: function (e) { for (var _module, i = 0, length = e.data.length; i < length; i++) { _module = e.data[i]; if (_module.name === 'jquery') { // trap jQuery here while removing it from the global object (function ($) { YUI.add('jquery', function (Y) { Y.jQuery = $; }); }(jQuery.noConflict(true))); } } } }).use('jquery', function (Y) { var $ = Y.jQuery; $('foo').attr('bar', 'baz'); }); 

如果包含它们的脚本假定jQuery位于全局对象中(大多数情况下),则插件可能是一个问题。 所以我建议你自己托管它们并将它们包装在YUI.add