Load jQuery and plugins in YUI

你说的曾经没有我的故事 提交于 2019-12-23 03:08:21

问题


I am trying to load jQuery as a YUI module, without adding it to the global scope.

The best I came up with, was to create a global module.exports so that jQuery thinks it is in a common js pattern, and does not create a global jQuery object...

// 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);

})

DEMO: http://jsfiddle.net/syvGZ/2/

Is there a better way to load jQuery within YUI without touching the global scope?


回答1:


You're on the right track with using onProgress, but you don't need to jump through all the hoops of cloning and faking module.exports. The trick is to use jQuery.noConflict().

jQuery.noConflict does two things:

  • It returns the jQuery function
  • It restores a previous version of jQuery if it was present, or it removes jQuery from the global object

Here's an illustration of how it works:

<script src="jquery.1.8.js"></script>
<script>
var jQuery18 = jQuery;
</script>
<script src="jquery.1.9.js"></script>
<script>
// the true parameter makes this work for both the $ and jQuery global variables, not just the $
var jQuery19 = jQuery.noConflict(true);
alert('is the global jQuery is jQuery19? ' + (jQuery === jQuery19)); // false
alert('is jQuery19 the same as jQuery18? ' + (jQuery19 === jQuery19)); // false
alert('is the global jQuery the same as jQuery18? ' + (jQuery === jQuery18)); // true
</script>

Another issue is that since YUI expects scripts with concatenated modules, e.name doesn't refer to the name of the module, but instead to the URL of the script that was just loaded. The names of the modules loaded in that script can be found in an array in e.data. This just means that you need to iterate over e.data to figure out if jQuery was loaded.

To sum it up, your script should look like this:

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');
});

Plugins could be an issue if the scripts that contain them assume jQuery is in the global object (most do). So I suggest you host them yourself and wrap them in YUI.add.



来源:https://stackoverflow.com/questions/17363701/load-jquery-and-plugins-in-yui

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!