简体   繁体   English

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

[英]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. 我正在尝试将最新版本的timepicker插件用于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. 另一个库已经以较早的版本( 1.0.4 )加载了它,但是我想使用最新的( 1.4.5 )版本。

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. 我确实看到,可以使用noConflict在页面上加载多个版本的jQuery,然后将其附加到其他版本的jQuery,但是我认为应该有一种更简单的方法。

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: 我试了一下,它不起作用-我认为是因为变量被引用了,所以可能需要实例化它们-我不是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>

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插件版本
  • jQuery plugins noConflict jQuery插件noConflict
  • load a jQuery plugins in a different namespace 在另一个命名空间中加载jQuery插件
  • load a jQuery plugins in a different domain 在其他域中加载jQuery插件
  • load a jQuery plugins in a different context 在不同的上下文中加载jQuery插件

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 该Web应用程序正在使用(non-jquery)插件,该插件具有依赖于timepicker插件的早期版本( 1.0.4 )的大型代码库。
  • 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) 我不想编写依赖于timepicker插件的早期版本( 1.0.4 )的代码,就像依赖其他代码库加载较旧的版本一样(更新时可能会中断)

So, I agree that using two versions of a jQuery plugin is not ideal. 因此,我同意使用两个版本的jQuery插件并不理想。 However, I do need to add in functionality from a later version of the jQuery timepicker plugin. 但是,我确实需要从更高版本的jQuery timepicker插件中添加功能。 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. 我相信可以做到这一点,也许可以使用Javascript的原型设计和继承,而不必像@ Oliboy50建议的那样对插件的源代码进行查找和替换而对其进行“黑客攻击”

Are there any Javascript pros who could demonstrate how to do this in (even though it is not ideal)? 有没有Java专家可以证明如何做到这一点(即使它不是理想的)?

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. 请注意:是的,我们已经确定尝试这样做是“一个坏主意”,但是原则上我想知道Javascript的原型语言是否允许这样做。 noconflict (ie loading multiple versions of jQuery) was already mentioned in comments and answers. 在评论和答案中已经提到了noconflict (即加载多个版本的jQuery)。 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 . 在这个jsfiddle( http://jsfiddle.net/RVyKM/ )中,我将timepickertimepickertwo并将datetimepicker替换为datetimepickertwo So you can use both your old timepicker plugin version 1.0.4 and your new timepickertwo plugin version 1.4.5... 因此,您既可以使用旧的时间选择器插件版本1.0.4,也可以使用新的时间选择器插件版本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. 其次,如果插件是通过RequireJS在单独的上下文中加载的,则它在jQuery ui小部件上没有句柄。 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. 换句话说,您可以引入插件并将其附加到单独的jQuery实例,但是jquery ui仅将一个全局div用于datepicker,并且单独的实例不起作用。 I've put together the following example (See full jsfiddle ): 我整理了以下示例(请参阅完整的jsfiddle ):

HTML 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 使用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. 我可以看到的唯一解决方案是@ Oliboy50建议的方法,克隆源并重命名插件。

EDIT 编辑

Hmm... Maybe this works ( fiddle ): 嗯...也许这行得通( 小提琴 ):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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