Na mojej stronie internetowej ładuję większość skryptów asynchronicznie za pomocą RequireJs. Proszę zobaczyć następujące mojej konfiguracji RequireJs:Wystąpił problem podczas ładowania wielu wersji jQuery
require.config({
paths: {
'jquery': '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery'
},
shim: {
'jquery.accordion': {
deps: ['jquery']
}
}
});
że mam następujący kod zdefiniowany w organizmie, aby załadować plik asynchronicznie:
require(['DisplayAccordion']);
Gdzie DisplayAccordion.js zawiera następujące elementy:
define(['jquery', 'jquery.accordion'], function($) {
$(function() {
$('.xyz').accordion();
});
});
Uwaga: jquery.accordion to po prostu wtyczka jQuery, która nie obsługuje AMD i wymaga zdefiniowania globalnej zmiennej jQuery.
To działa dobrze, ale teraz mówię, że umieszczam odnośnik do skryptu na mojej stronie w bibliotece innej firmy. Na przykład:
<script src="//example.com/ThirdParty.js"></script>
Tam, gdzie biblioteka stron trzecich ładuje swoją własną wersję jQuery. Teraz otrzymuję błąd:
Object doesn't support property or method 'accordion'.
Po wstępnej poprzez kod znalazłem, że wykonuje się w następującej kolejności:
- ThirdParty.js
- jquery.min.js - wersja strony trzeciej
- jquery.min.js - moja wersja
- jquery.accordion.js - gdzie $ punkty odniesienia do mojej wersji jQuery
- Displ ayAccordion.js (funkcja zwrotna) - gdzie $ wskazuje na trzecią wersję jQuery
Teraz widzę, dlaczego dostaję błąd, ponieważ wtyczka jest dołączona do innego obiektu. Jednak nie jestem pewien, dlaczego to zrobiłoby.
Poniższe informacje wyjaśniają, dlaczego użycie $ .noConflict (true) nie zadziała.
Po przeprowadzeniu badań w tej sprawie. I zmodyfikowane mój config:
require.config({
paths: {
'jquery': '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery'
},
map: {
'*': { 'jquery': 'jquery-private' },
'jquery-private': { 'jquery': 'jquery' }
},
shim: {
'jquery.accordion': {
deps: ['jquery']
}
}
});
Gdzie jQuery private.js jest zdefiniowany jako:
define(['jquery'], function($) {
return $.noConflict(true);
});
Należy pamiętać, że ta została podjęta z http://www.requirejs.org/docs/jquery.html#noconflictmap
Teraz wykonuje się w następującej kolejności:
- ThirdParty.js
- jquery.min.js - wersja osoba trzecia
- jQuery private.js (funkcja zwrotna)
- jquery.min.js - moja wersja
- jquery.accordion.js - gdzie $ jest niezdefiniowana
- DisplayAccordion .js (funkcja callback) - gdzie $ punkty do trzeciej wersji partyjnej jQuery
Jak można sobie wyobrazić, to nie będzie działać albo od $ jest zdefiniowana w pliku jquery.accordion.js.
Po abit dalszego debugowania odkryłem biblioteki strona trzecia wzywa również:
$.noConflict(true);
Chyba rozumiem, co się tu dzieje. Kiedy wywołuje $ .noConflict (true) w bibliotece trzeciej strony, próbuje ustawić globalne zmienne $ i jQuery do poprzedniej wersji. Ponieważ jednak nie załadowano poprzedniej wersji, jest ona ustawiona na undefined.
Teraz, gdy wywołuje jquery-private.js i zwraca $ .noConflict (true), zwróci globalną zmienną jQuery, która została ustawiona na undefined. Jednak teraz ustawi globalną zmienną jQuery na trzecią wersję biblioteki.
Tak więc po załadowaniu pliku jquery.accordion $ jest niezdefiniowany. Ale kiedy następnie wywołuje DisplayAccordion.js, odwołuje się teraz do trzeciej wersji biblioteki jQuery.
Byłbym wdzięczny, gdyby ktoś mógł zaproponować poprawkę. Dzięki
To nie rozwiąże problemu. Zauważ, jak w ostatnim kroku próby OP (obu prób) moduł 'DisplayAccordion', który * robi * ładuje' jquery' jako moduł, pobiera trzecią wersję jQuery zamiast wersji, którą chce OP. To, co sugerujesz, zrobi to samo: 'jquery.accordion' otrzyma wersję jQuery innej firmy niż wersję OP. Jeśli wyjaśnię to w mojej odpowiedzi, dlaczego tak się dzieje. – Louis
Doh - widzę - główny problem z twoją odpowiedzią polega po prostu na tym, że ignoruje fakt, że OP nie ma kontroli nad kolejnością ładowania (dlatego nie pomaga w żaden inny sposób niż informacyjny). Jak o użyciu modułu 'jquery-private' zamiast' jquery' - nadal będzie wymagać zapakowania akordeonu, ale powinno pozwolić na użycie poprawnej wersji ... – Rycochet
Użycie 'jquery-private' nie rozwiąże problemu . Tak postąpił PO podczas drugiej próby. Jak wskazałem w moim poprzednim komentarzu, w * obu * próbach 'DisplayAccordion' pojawia się niewłaściwa wersja. Co do wartości mojej odpowiedzi, tak, przeczytałem komentarz PO i zdałem sobie sprawę, że nie zadziała, jeśli nie można ograniczyć kolejności ładunków kodu OP względem "ThirdParty.js". Dla przypomnienia, OP dodał * zasadnicze * zastrzeżenie, że nie ma kontroli nad kolejnością ładowania * po * wysłałem odpowiedź. W każdym razie dla mnie oznacza to, że kolejność powinna być ograniczona. – Louis