Czy mogę używać wielu wersji jQuery na tej samej stronie?

426

Projekt, nad którym pracuję, wymaga użycia jQuery na stronach internetowych klientów. Klienci wstawią fragment kodu, który dostarczymy, który zawiera kilka <script>elementów, które budują widget w <script>utworzonym <iframe>. Jeśli nie korzystają już z najnowszej wersji jQuery, obejmie to również (najprawdopodobniej) <script>wersję jQuery dla Google.

Problem polega na tym, że niektórzy klienci mogą już mieć starszą wersję jQuery. Chociaż może to działać, jeśli jest to co najmniej całkiem nowa wersja, nasz kod opiera się na niektórych niedawno wprowadzonych funkcjach w bibliotece jQuery, więc na pewno będą przypadki, gdy wersja jQuery klienta jest po prostu za stara. Nie możemy wymagać od nich aktualizacji do najnowszej wersji jQuery.

Czy istnieje sposób załadowania nowszej wersji jQuery do użytku wyłącznie w kontekście naszego kodu, który nie będzie zakłócał ani nie wpływał na żaden kod na stronie klienta? Idealnie byłoby, gdybyśmy mogli sprawdzić obecność jQuery, wykryć wersję, a jeśli jest za stara, to w jakiś sposób załaduj najnowszą wersję, aby użyć jej w naszym kodzie.

Wpadłem na pomysł załadowania jQuery w <iframe>domenie klienta, która obejmuje także naszą <script>, co wydaje się być wykonalne, ale mam nadzieję, że istnieje bardziej elegancki sposób (nie wspominając o wydajności i złożoności kar dodatkowe <iframe>s).

Klecić
źródło
1
Natrafiłem na ten sam problem. Ponieważ używałem jQuery tylko kilka razy w swoim osadzonym skrypcie, postanowiłem całkowicie zrezygnować z jQuery i po prostu zrobić to, czego potrzebowałem bezpośrednio w JavaScript. Ta strona: youmightnotneedjquery.com była bardzo przydatna.
Ferruccio,

Odpowiedzi:

578

Tak, jest to wykonalne dzięki trybowi noconflict w 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>

Następnie zamiast tego $('#selector').function();zrobiłbyś jQuery_1_3_2('#selector').function();lub jQuery_1_1_3('#selector').function();.

ceejayoz
źródło
13
Wielkie dzięki, ceejayoz! To wygląda na realne rozwiązanie - jedynym potencjalnym problemem jest to, że nie mam żadnej kontroli nad pierwszą częścią twojego kodu (przypisywanie starszej wersji jQuery do innego aliasu). To, w jaki sposób klient korzysta z jQuery, będzie się różnić i będzie poza moją kontrolą. Czy mogę bezpiecznie korzystać z drugiej połowy, czy też obie biblioteki muszą wywoływać funkcję noConflict ()?
Bungle
7
Tak, powinieneś być w stanie skorzystać z drugiej połowy.
ceejayoz
9
Czy to jest naprawdę przezroczyste dla oryginalnej strony? Jeśli użyją $ lub jQuery po tym fragmencie kodu, czy odnosi się to do ich własnej wersji jQuery lub nowszej (która prawdopodobnie ma zainstalowanych mniej wtyczek)?
Wim,
2
@ ceejayoz, co się stanie, jeśli masz funkcję samo-wywołującą, która wykorzystuje dużo $. Musielibyśmy zmienić każdy $ na jquery_1_3_2, w tej sekcji o noconflikcie ???
klewis 30.04.13
37
@blachawk Nie, po prostu pseudonim. (function($) { /*your code here*/ }(jquery_x_x_x));
Fabrício Matté
85

Po przyjrzeniu się temu i wypróbowaniu okazało się, że tak naprawdę nie pozwala na uruchomienie więcej niż jednego wystąpienia jquery na raz. Po przeszukaniu okazało się, że to załatwiło sprawę i było o wiele mniej kodu.

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

Zatem dodanie „j” po „$” było wszystkim, co musiałem zrobić.

$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();
        });
    });
Dziwny Mike
źródło
6
Aby uniknąć zmiany nazwy zmiennej jquery w tak wielu miejscach, możesz po prostu zawrzeć swój stary kod wewnątrz:(function($){ })($j)
Marinos An
36

Zaczerpnięte z http://forum.jquery.com/topic/multiple-versions-of-jquery-on-the-same-page :

  • Oryginalna strona ładuje swój plik „jquery.versionX.js” - $i jQuerynależy do wersji X.
  • Nazywasz swój „jquery.versionY.js” - teraz $i jQuerynależysz do wersji Y, plus _$i_jQuery należą do versionX.
  • my_jQuery = jQuery.noConflict(true);- teraz $i jQuerynależą do wersji X, _$i _jQueryprawdopodobnie są zerowe, i my_jQueryjest w wersji Y.
Juan Vidal
źródło
9
Nie zrozumiałem, dopóki nie poszedłem do linku. „Gdy załadujesz plik jQuery.xxjs, zastąpi on istniejące zmienne $ i jQuery ... ALE zachowuje ich kopię zapasową (w _ $ i _jQuery). Po wywołaniu noConflict (true) przywracasz sytuację taką, jaka była wcześniej twoje włączenie js ”
Colin
W przyszłości prosimy o wyraźniejsze odniesienie do źródeł zewnętrznych. Aby uzyskać więcej informacji, zobacz stackoverflow.com/help/referencing
Matt
23

Na twojej stronie możesz mieć tyle różnych wersji jQuery, ile chcesz.

Użyj 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> 

DEMO | Źródło

martynas
źródło
23

Możliwe jest załadowanie drugiej wersji jQuery, użyj go, a następnie przywróć do oryginału lub zachowaj drugą wersję, jeśli wcześniej nie było załadowane jQuery. Oto przykład:

<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
źródło
5

Chciałbym powiedzieć, że zawsze musisz używać najnowszych lub najnowszych stabilnych wersji jQuery. Jeśli jednak potrzebujesz trochę pracy z innymi wersjami, możesz dodać tę wersję i zmienić jej nazwę na $inną. Na przykład

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

Zajrzyj tutaj, jeśli napiszesz coś za pomocą, $a otrzymasz najnowszą wersję. Ale jeśli chcesz zrobić coś ze starym, po prostu użyj $oldjQueryzamiast$ .

Oto przykład

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

Próbny

gdmanandamohon
źródło