如何在同一页面上加载多个版本的jQuery插件? [英] How can I load multiple versions of a jQuery plugin on the same page?

查看:133
本文介绍了如何在同一页面上加载多个版本的jQuery插件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 timepicker插件的最新版本用于jQuery UI.

>

另一个库已经以较早版本(1.0.4)加载了它,但是我想使用最新版本(1.4.5).

在源代码中,插件会在继续操作之前检查它是否已经加载:

$.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中的功能,但是我不希望我的代码在更新或替换另一个库时中断.

  • 该Web应用程序正在使用(非jquery)插件,该插件具有依赖于timepicker插件的早期版本(1.0.4)的大型代码库
  • 这不是我更新其他插件代码库的地方
  • 我不想编写依赖于timepicker插件早期版本(1.0.4)的代码,就像依赖其他代码库加载较旧版本一样(更新时可能会中断) )

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

是否有任何Java专家可以证明如何做到这一点(即使并不理想)?

请注意:是的,我们已经确定尝试这样做是一个坏主意",但是原则上我想知道Javascript的原型语言是否允许这样做. noconflict(即加载jQuery的多个版本)已在评论和答案中提及.尽管这行得通",但这不是我要找的答案.另外,用查找和替换修改插件源代码也不是一个很好的解决方案.

解决方案

这似乎是不可能的,尤其是对于此插件.首先,该插件不允许自己重新定义/覆盖:

/*
 * 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用作日期选择器,并且该单独的实例不起作用.我整理了以下示例(请参阅完整的 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建议的解决方案,克隆源并重命名插件.

编辑

嗯...也许可行(小提琴):

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

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 (i.e. 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.

解决方案

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

这篇关于如何在同一页面上加载多个版本的jQuery插件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆