Posso usar várias versões do jQuery na mesma página?

427

Um projeto em que estou trabalhando exige o uso do jQuery nas páginas da Web dos clientes. Os clientes inserirão um pedaço de código que forneceremos, incluindo alguns <script>elementos que constroem um widget em um <script>-criado <iframe>. Se eles ainda não estiverem usando a versão mais recente do jQuery, isso também incluirá (provavelmente) um <script>para a versão hospedada do Google do jQuery.

O problema é que alguns clientes já podem ter uma versão mais antiga do jQuery instalada. Embora isso possa funcionar se for pelo menos uma versão bastante recente, nosso código depende de algumas funcionalidades introduzidas recentemente na biblioteca jQuery, portanto, haverá casos em que a versão jQuery de um cliente é muito antiga. Não podemos exigir que eles atualizem para a versão mais recente do jQuery.

Existe alguma maneira de carregar uma versão mais recente do jQuery para usar somente dentro do contexto do nosso código, que não interfira ou afete qualquer código na página do cliente? Idealmente, talvez pudéssemos verificar a presença de jQuery, detectar a versão e, se ela for muito antiga, de alguma forma carregar a versão mais recente apenas para uso em nosso código.

Eu tive a ideia de carregar o jQuery em um <iframe>domínio do cliente que também inclui o nosso <script>, o que parece viável, mas espero que exista uma maneira mais elegante de fazer isso (sem mencionar as penalidades de desempenho e complexidade do <iframe>s extras ).

Estragar
fonte
1
Eu tive o mesmo problema. Como eu só usei o jQuery algumas vezes no meu script incorporado, decidi renunciar completamente ao jQuery e simplesmente fazer o que precisava diretamente em JavaScript. Este site: youmightnotneedjquery.com foi extremamente útil.
Ferruccio

Respostas:

578

Sim, é possível devido ao modo de noconflict do jQuery. http://blog.nemikor.com/2009/10/03/using-multiple-versions-of-jquery/

<!-- load jQuery 1.1.3 -->
<script type="text/javascript" src="http://example.com/jquery-1.1.3.js"></script>
<script type="text/javascript">
var jQuery_1_1_3 = $.noConflict(true);
</script>

<!-- load jQuery 1.3.2 -->
<script type="text/javascript" src="http://example.com/jquery-1.3.2.js"></script>
<script type="text/javascript">
var jQuery_1_3_2 = $.noConflict(true);
</script>

Então, em vez de $('#selector').function();, você faria jQuery_1_3_2('#selector').function();ou jQuery_1_1_3('#selector').function();.

ceejayoz
fonte
13
Muito obrigado, ceejayoz! Parece uma solução viável - o único problema em potencial é que não tenho controle sobre a primeira parte da sua solução de código (atribuindo a versão mais antiga do jQuery a um alias diferente). Como o cliente está usando o jQuery varia e está fora do meu controle. Posso usar com segurança a segunda metade com segurança ou as duas bibliotecas precisam chamar noConflict ()?
Bungle
7
Sim, você poderá usar apenas a segunda metade.
ceejayoz
9
Isso é realmente transparente para a página original? Se eles usassem $ ou jQuery após esse trecho de código, isso se referiria à própria versão do jQuery ou à versão mais recente (que possivelmente possui menos plug-ins instalados)?
Wim
2
@ceejayoz, o que acontece se você tiver uma função auto-invocadora que usa muito $ nela. Teríamos que mudar cada $ único para jquery_1_3_2, dentro dessa seção de não-conflito ???
klewis
37
@blachawk Não, apenas o pseudônimo. (function($) { /*your code here*/ }(jquery_x_x_x));
Fabrício Matté
85

Depois de analisar e experimentar, descobri que na verdade não permitia que mais de uma instância do jquery fosse executada por vez. Depois de pesquisar, descobri que isso fazia exatamente o truque e era muito menos código.

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" type="text/javascript"></script>
    <script>var $j = jQuery.noConflict(true);</script>
    <script>
      $(document).ready(function(){
       console.log($().jquery); // This prints v1.4.2
       console.log($j().jquery); // This prints v1.9.1
      });
   </script>

Então, basta adicionar o "j" após o "$".

$j(function () {
        $j('.button-pro').on('click', function () {
            var el = $('#cnt' + this.id.replace('btn', ''));
            $j('#contentnew > div').not(el).animate({
                height: "toggle",
                opacity: "toggle"
            }, 100).hide();
            el.toggle();
        });
    });
Mike estranho
fonte
6
Para evitar renomeando variável jquery em tantos lugares que você poderia apenas colocar o seu código antigo dentro do seguinte:(function($){ })($j)
Marinos Um
36

Retirado de http://forum.jquery.com/topic/multiple-versions-of-jquery-on-the-same-page :

  • A página original carrega seu "jquery.versionX.js" - $e jQuerypertence à versãoX.
  • Você chama seu "jquery.versionY.js" - agora $e jQuerypertence à versãoY, mais _$e _jQuerypertence à versãoX.
  • my_jQuery = jQuery.noConflict(true);- agora $e jQuerypertencem à versãoX, _$e _jQueryprovavelmente são nulos, e my_jQuerysão a versãoY.
Juan Vidal
fonte
9
Eu não entendi até que eu fui para o link. "Quando você carrega o jQuery.xxjs, ele substitui os vars $ e jQuery existentes ... MAS mantém uma cópia de backup deles (em _ $ e _jQuery). Ao chamar noConflict (true), você restaura a situação como antes sua inclusão js "
Colin
No futuro, seja mais explícito sobre a referência a fontes externas. Para obter mais informações, consulte stackoverflow.com/help/referencing
Matt
23

Você pode ter quantas versões diferentes do jQuery em sua página desejar.

Use jQuery.noConflict():

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script>
<script>
    var $i = jQuery.noConflict();
    alert($i.fn.jquery);
</script> 

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
    var $j = jQuery.noConflict();
    alert($j.fn.jquery);
</script> 

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script>
    var $k = jQuery.noConflict();
    alert($k.fn.jquery);
</script> 

DEMONSTRA | Fonte

martynas
fonte
23

É possível carregar a segunda versão do jQuery, usá-lo e, em seguida, restaurar o original ou manter a segunda versão, se não houvesse o jQuery carregado anteriormente. Aqui está um exemplo:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript">
    var jQueryTemp = jQuery.noConflict(true);
    var jQueryOriginal = jQuery || jQueryTemp;
    if (window.jQuery){
        console.log('Original jQuery: ', jQuery.fn.jquery);
        console.log('Second jQuery: ', jQueryTemp.fn.jquery);
    }
    window.jQuery = window.$ = jQueryTemp;
</script>
<script type="text/javascript">
    console.log('Script using second: ', jQuery.fn.jquery);
</script>
<script type="text/javascript">
    // Restore original jQuery:
    window.jQuery = window.$ = jQueryOriginal;
    console.log('Script using original or the only version: ', jQuery.fn.jquery);
</script>
Tomas Kirda
fonte
5

Gostaria de dizer que você deve sempre usar as versões estáveis ​​mais recentes ou recentes do jQuery. No entanto, se você precisar trabalhar com outras versões, poderá adicionar essa versão e renomeá-la $para outro nome. Por exemplo

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
<script>var $oldjQuery = $.noConflict(true);</script>

Olhe aqui se você escrever algo usando, $então você obterá a versão mais recente. Mas se você precisar fazer algo com o antigo, basta usar em $oldjQueryvez de $.

Aqui está um exemplo

$(function(){console.log($.fn.jquery)});
$oldjQuery (function(){console.log($oldjQuery.fn.jquery)})

Demo

gdmanandamohon
fonte