如何在同一页面上加载多个版本的jQuery插件?

时间:2014-06-24 20:06:56

标签: javascript jquery jquery-ui jquery-ui-datepicker datetimepicker

我正在尝试将最新版本的timepicker addon用于jQuery UI。

另一个库已经在早期版本(1.0.4)加载了它,但我想使用最新版本(1.4.5)。

In the source,插件会在继续之前检查它是否已经加载:

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

我做了很多寻找方法,但没有提出任何帮助。我确实看到可以使用noConflict在页面上加载多个版本的jQuery,然后将它附加到不同版本的jQuery,但我认为应该有一个更简单的方法。

我试了一下它没有用 - 我想因为变量被引用而且它们可能需要实例化 - 我不是JS专家但至少我在尝试:

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

编写代码感觉很脏,再次,它不起作用。所以,在没有任何运气之后,我尝试了更多,但仍未提出任何问题。我试着寻找:

  • 在同一页面上加载多个jQuery插件版本
  • jQuery插件noConflict
  • 在不同的命名空间中加载jQuery插件
  • 在不同的域中加载jQuery插件
  • 在不同的上下文中加载jQuery插件

这样做很简单吗?我只是没有搜索或正确的事情,或者它是不可能的?

为什么我要尝试这个

我需要较新版本的timepicker的功能,但我不希望我的代码在更新或替换其他库时中断。

  • 网络应用正在使用(非jquery)插件,其中包含大量代码库,该插件依赖于timepicker addon的早期版本(1.0.4
  • 这不是我更新其他插件的代码库的地方
  • 我不想编写依赖于timepicker插件的早期版本(1.0.4)的代码,因为它依赖于其他代码库来加载旧版本(并且可能会破坏它已更新)

所以,我同意使用两个版本的jQuery插件并不理想。但是,我确实需要在更高版本的jQuery timepicker插件中添加功能。 我相信有可能做到这一点,可能使用Javascript的原型设计和继承,而不必“破解”,因为@ Oliboy50建议对插件的源代码进行查找和替换。

是否有任何Javascript专业人员可以演示如何执行此操作(即使它不理想)?

请注意:是的,我们已经确定尝试这样做是“一个坏主意”,但原则上我想知道Javascript的原型语言是否允许这样做。 noconflict(即加载jQuery的多个版本)已在评论和答案中提及。虽然这“会起作用”,但这不是我正在寻找的答案。此外,使用查找和替换修改插件源代码也不是一个优雅的解决方案。

2 个答案:

答案 0 :(得分:3)

我认为使用两个不同版本的插件已经是件坏事了。因此,如果您的解决方案可能是更改插件的名称,我认为您不会介意。

在这个jsfiddle(http://jsfiddle.net/RVyKM/)中,我用timepicker替换(我认为)timepickertwo,用datetimepicker替换datetimepickertwo。所以你可以使用旧的timepicker插件版本1.0.4和新的timepickertwo插件版本1.4.5 ...

但是,请注意,这是一个坏主意,恕我直言。

答案 1 :(得分:1)

这似乎不可能,特别是对于这个插件。首先,插件不允许自己重新定义/覆盖:

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

所以你不能简单地加载旧版本,初始化它,然后在旧版本之上加载新版本,新版本将不会加载。

其次,如果插件是在一个单独的上下文中加载的,比如通过RequireJS加载,那么它就没有jquery ui小部件的句柄。换句话说,你可以引入插件并将它附加到一个单独的jQuery实例,但是jquery ui只使用一个全局div作为datepicker,而单独的实例不能使用它。我将以下示例放在一起(请参阅完整的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);

我能看到的唯一解决方案是@ Oliboy50建议,克隆源并重命名插件。

修改

嗯......也许这有效(fiddle):

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