在页面上包含两个版本的 jQuery 而不会影响旧插件

Posted

技术标签:

【中文标题】在页面上包含两个版本的 jQuery 而不会影响旧插件【英文标题】:Include two versions of jQuery on a page without affecting old plugins 【发布时间】:2012-06-06 13:32:27 【问题描述】:

我们的 drupal 站点使用我们尚未升级的 jQuery 版本 1.2.1 运行。

问题是这样的:

我们需要添加一个名为 jQuery Tokeninput 的新插件,但它仅适用于最新的 jQuery 版本。我们尝试在旧版本中添加最新的 jQuery 版本,但结果很奇怪。

我的问题是,如何在不影响旧 jQuery 插件的情况下包含最新的 jQuery 文件?

【问题讨论】:

【参考方案1】:

方法#1:(推荐)

你可以这样做:

<script type='text/javascript' src='js/jquery_1.7.1.js'></script>   
<script type='text/javascript'>  
 // In case you wonder why we pass the "true" parameter,
 // here is the explanation:
 //   - When you use jQuery.noConflict(), it deletes
 //     the "$" global variable.
 //   - When you use jQuery.noConflict(true), it also
 //     deletes the "jQuery" global variable.
 var $jq = jQuery.noConflict(true);  
</script>  
<script type='text/javascript' src='js/jquery_1.2.1.js'></script> 

这样,当您想要使用新版本的 jquery 而不是 $ 制作的东西时,请使用 $jq

$jq('.selector').on('click', function()  
    //do something  
);

方法 #2:(可能会破坏您网站上的内容 - 不推荐)

在您的template.php 文件中:

<?php
function theme_name_preprocess(&$vars, $hook) 
if (arg(0) != 'admin' && $hook == "page") 
// Get an array of all JavaScripts that have been added
$javascript = drupal_add_js(NULL, NULL, 'header');

// Remove the original jQuery library
unset($javascript['core']['misc/jquery.js']);

// Add in our new jQuery library
// We do it this way to keep the includes in the same order
$core = array(
//Alternative jQuery
drupal_get_path('theme', 'theme_name').'/js/libs/jquery-1.7.1.min.js' => array(
'cache' => TRUE,
'defer' => FALSE,
)
);

// Merge back into the array of core JavaScripts
$javascript['core'] = array_merge($javascript['core'], $core);

// Rerender the block of JavaScripts
$vars['scripts'] = drupal_get_js(NULL, $javascript);


确保只在您网站的前端执行此操作。如果它们依赖于 Drupal 的 jQuery 版本,它可能会弄乱管理工具栏。

【讨论】:

第二种方法不错。但是,第一种方法可能会破坏您的网站。 “jQuery 更新”模块在 d6 上只能获取 1.3.* 版本是有原因的。 感谢您的建议。我更新了我的答案以推荐更好的解决方案。 另外,使用jQuery.noConflict( true ),否则两个版本的jQuery会发生冲突:-)。 jQuery.noConflict() 只是删除了$ 变量,传递true 参数也删除了jQuery 变量。【参考方案2】:

以下脚本...

与预先存在的脚本完全向后兼容

应该没有副作用(除了增加额外的JS下载有明显的副作用)

允许以任何顺序使用任何版本的 jQuery -- 您可以将“默认”设置为 jQuery 的旧版本,将“附加”设置为新版本,反之亦然。

如何在同一页面上使用 2 个版本的 jQuery

<!-- IMPORTANT: ORDER is vital. Do not change the order of the following. -->

<script src="//code.jquery.com/jquery-1.4.2.min.js"></script>
<script>
    // Save original jQuery version to another variable
    var $Original = jQuery.noConflict(true);
</script>

<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script>
    // Save new jQuery version to another variable
    var $v1_11_0 = jQuery.noConflict(true);

    // Replace the original jquery version on $ and jQuery so pre-existing scripts don't break
    // No need to declare "var" here since the $ and jQuery still exist as "undefined"
    $ = $Original;
    jQuery = $Original;

    // Optional: Here I'm saving new jQuery version as a method of "$" -- it keeps it more organized (in my opinion)
    $.v1_11_0 = $v1_11_0;
</script>

在这里查看它的实际效果:

http://jsfiddle.net/dd94h/

这是您可以放入 html 文件进行测试的整个 HTML

<!DOCTYPE html>
<html>
<head>
    <title>jQuery within jQuery</title>
    <style media="all" type="text/css">
        h1 span  font-weight: normal; 
    </style>

    <!-- IMPORTANT: ORDER is vital. Do not change the order of the following. -->

    <script src="//code.jquery.com/jquery-1.4.2.min.js"></script>
    <script>
        // Save original jQuery version to another variable
        var $Original = jQuery.noConflict(true);
    </script>

    <script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
    <script>
        // Save new jQuery version to another variable
        var $v1_11_0 = jQuery.noConflict(true);

        // Replace the original jquery version on $ and jQuery so pre-existing scripts don't break
        // No need to declare "var" here since the $ and jQuery still exist as "undefined"
        $ = $Original;
        jQuery = $Original;

        // Optional: Here I'm saving new jQuery version as a method of "$" -- it keeps it more organized (in my opinion)
        $.v1_11_0 = $v1_11_0;
    </script>
</head>
<body>
<h1>Default jQuery: <span id="default-jquery">Loading...</span></h1>
<h1>Additional jQuery: <span id="additional-jquery">Loading...</span></h1>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed id felis quam. Morbi ultrices nisi vel odio vestibulum nec faucibus diam congue. Etiam cursus, turpis id rutrum adipiscing, ligula justo rhoncus ipsum, sed posuere diam orci vel mi. Etiam condimentum tincidunt metus, non dictum ligula hendrerit et. Nulla facilisi. Aenean eleifend volutpat nibh, eu tempor nulla auctor ac. Proin ultrices cursus scelerisque. Curabitur sem sapien, tempus et dictum nec, viverra vel odio. Nulla ullamcorper nisl a dolor laoreet eu eleifend tellus semper. Curabitur vitae sodales nisl. Donec tortor urna, viverra sed luctus in, elementum sit amet turpis.</p>

<script>
    // Continue to use "$" for the original jQuery version
    $( document ).ready(function()
        $('#default-jquery').text($().jquery);
    );

    // Use $.v1_11_0(...) for the newly-added version
    $.v1_11_0( document ).ready(function()
        $.v1_11_0('#additional-jquery').text($.v1_11_0().jquery);
    );
</script>
</body>
</html>

【讨论】:

【参考方案3】:

您知道,有一个jQuery update module 可以为您更新 jQuery 版本,而无需您编写代码。如果感兴趣,请查看它,但我认为该模块不会保留旧的 jQuery 版本,而是用新版本替换它。

我可能还建议您尝试升级 jQuery 的版本并只使用最新的版本,看看它是否确实破坏了其他功能。

【讨论】:

你是对的,它取代了它,这基本上不是OP所要求的。 jQuery 更新很棒,但前提是你没有一个包含大量旧插件且没有空间进行回归测试的 MASSIVE 站点 (sob)。

以上是关于在页面上包含两个版本的 jQuery 而不会影响旧插件的主要内容,如果未能解决你的问题,请参考以下文章

jQuery-UI 自动完成不会显示在 jQuery-UI 对话框中

jQuery Mobile 应用程序中同时显示的所有页面

JS文件不会出现在Scripts文件夹中

jQuery库与内联脚本冲突

jquery在iframe下失效

如何在具有 2 个 jQuery 版本的页面/站点上使用 select2