简体   繁体   中英

How can I load multiple versions of a jQuery plugin on the same page?

I'm trying to use the latest version of the timepicker addon for jQuery UI.

Another library already loaded it at an earlier version ( 1.0.4 ) but I want to use the latest ( 1.4.5 ) version.

In the source , the plugin checks to see if it has already been loaded before proceeding:

$.ui.timepicker = $.ui.timepicker || {};
if ($.ui.timepicker.version) {
    return;
}

I did a lot of searching for ways to do this but didn't come up with anything helpful. I did see that it might be possible to load multiple versions of jQuery on the page using noConflict and then attach it to a different version of jQuery but I thought there should be an easier way.

I gave this a try it is not working - I think because the variables are getting referenced and they maybe need to be instantiated instead - I'm not a JS expert but at least I'm trying:

// jQuery, jQueryUi, and the 1.0.4 version loaded beforehand

<script>
    var _old_jquery_ui_timepicker = jQuery.ui.timepicker;
    var _old_jquery_ui_timepicker_function = jQuery.fn.datetimepicker;
    jQuery.ui.timepicker = null;
</script>

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-ui-timepicker-addon/1.4.5/jquery-ui-timepicker-addon.min.js"></script>

<script>

    jQuery.ui.mytimepicker = jQuery.ui.timepicker;
    jQuery.ui.timepicker = _old_jquery_ui_timepicker;

    jQuery.fn.mydatetimepicker = jQuery.fn.datetimepicker;
    jQuery.fn.datetimepicker = _old_jquery_ui_timepicker_function;

</script>

Writing that code felt dirty, and again, it didn't work. So, after not having any luck with that I tried searching more and still didn't come up with anything. I tried searching for:

  • loading multiple jQuery plugin versions on the same page
  • jQuery plugins noConflict
  • load a jQuery plugins in a different namespace
  • load a jQuery plugins in a different domain
  • load a jQuery plugins in a different context

Is this simple to do and I'm just not searching or the right thing or is it impossible?

Why I'm attempting this

I need features from the newer version of the the timepicker, but I don't want my code to break when the other library is updated or replaced.

  • The web app is using a (non-jquery) plugin with a large codebase that is reliant on the earlier version ( 1.0.4 ) of the timepicker addon
  • It's not my place to update the other plugin's codebase
  • I don't want to write code that is reliant on the earlier version ( 1.0.4 ) of the timepicker addon, as would be reliant on the other codebase to load the older version (and would possibly break when that was updated)

So, I agree that using two versions of a jQuery plugin is not ideal. However, I do need to add in functionality from a later version of the jQuery timepicker plugin. I believe it is possible to do this, maybe with Javascript's prototyping and inheritance, and without having to 'hack it' as @Oliboy50 suggests doing with a find-and-replace to the plugin's sourcecode.

Are there any Javascript pros who could demonstrate how to do this in (even though it is not ideal)?

Please note: yes, we have established that "it is a bad idea" to try and do this, but for principle I would like to know if Javascript's prototypal language would allow this to be done. noconflict (ie loading multiple versions of jQuery) was already mentioned in comments and answers. Although this "would work" it's not the answer I'm looking for. Also, modifying the plugin sourcecode with a find-and-replace is not really an elegant solution either.

I think that it's already a bad thing to use two differents version of a plugin. So I think you won't mind if you're solution could be to change the name of the plugin.

In this jsfiddle ( http://jsfiddle.net/RVyKM/ ), I replaced (I think) timepicker with timepickertwo and datetimepicker with datetimepickertwo . So you can use both your old timepicker plugin version 1.0.4 and your new timepickertwo plugin version 1.4.5...

But still, be aware that this is a bad idea, IMHO.

This doesn't appear to be possible, especially with this plugin. For one, the plugin doesn't allow itself to be redefined/overwritten:

/*
 * Lets not redefine timepicker, Prevent "Uncaught RangeError: Maximum call stack size exceeded"
 */
$.ui.timepicker = $.ui.timepicker || {};
if ($.ui.timepicker.version) {
    return;
}

So you can't simply load the older version, initialize it, and then load the newer version on top of the old one, the newer one won't load.

Secondly, if the plugin is loaded in a separate context, say via RequireJS, then it doesn't have a handle on the jquery ui widgets. In other words you can bring in the plugin and attach it to a separate jQuery instance, but then jquery ui only uses one global div for the datepicker and the separate instance doesn't work with it. I've put together the following example (See full jsfiddle ):

HTML

<script src="http://rawgit.com/trentrichardson/jQuery-Timepicker-Addon/v1.0.4/jquery-ui-timepicker-addon.js"></script>

<p><input id="date1" type="text" /></p>
<p><input id="date2" type="text" /></p>
<p><input id="date3" type="text" /></p>

<div id="qunit"></div>
<div id="qunit-fixture"></div>

Javascript

require.config({
    paths: {
        'jquery': '//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min',
        'jquery-ui': 'http://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min',
        'jquery.timepicker': 'http://rawgit.com/trentrichardson/jQuery-Timepicker-Addon/v1.4.5/dist/jquery-ui-timepicker-addon'
    },
    shim: {
        'jquery.timepicker': {
            deps: ['jquery', 'jquery-ui'],
            init: function(jquery) {
                return jquery.noConflict(true);   
            }
        }
    },
});

QUnit.test('global timepicker is 1.0.4', function (assert) {
    assert.ok($.timepicker.version == '1.0.4',
              $.timepicker.version);
});

$('#date1').timepicker();

require(['jquery', 'jquery.timepicker'], function ($) {
    QUnit.test('amd timepicker is 1.4.5', function (assert) {
        assert.ok($.timepicker.version == '1.4.5',
                  $.timepicker.version);
    });

    // Not working...
    $('#date2').datepicker();
});

setTimeout(function() {
    QUnit.test('global timepicker is still 1.0.4', function (assert) {
        assert.ok($.timepicker.version == '1.0.4',
                  $.timepicker.version);
    });

    $('#date3').timepicker();
}, 2000);

The only solution I can see is as @Oliboy50 suggests, clone the source and rename the plugin.

EDIT

Hmm... Maybe this works ( fiddle ):

// Maybe working...
$.datepicker = jQuery.datepicker;
$.fn.datepicker = jQuery.fn.datepicker;
$('#date2').timepicker();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM