2012-09-04 22 views
17

Ich schreibe ein Skript, das in Websites von Drittanbietern eingebettet werden soll, um ihnen Funktionalität hinzuzufügen. Ich habe vor kurzem meinen ziemlich unordentlichen benutzerdefinierten Ladecode rausgerissen und angefangen, ihn durch require zu ersetzen. Eine der Bibliotheken, die optional für mich geladen wird (hängt von einigen Parametern ab) ist jQuery.make requires jQuery nicht neu laden, wenn bereits auf Seite

Dies funktioniert gut, bis mein Skript auf einer Seite enthalten ist, die jQuery bereits eingeschaltet ist. In diesem Fall scheint einige Plugins teilweise geladen zu sein, requirejs lädt jQuery über die Version der Seite, und die Plugins brechen sofort.

Es ist nicht möglich, Clients zu fragen, ihre Seiten umzuschreiben, nur um dieses Skript zu verwenden. Ich möchte also herausfinden, ob jQuery bereits geladen ist. Wenn ja, überspringen Sie das Laden über requirejs und verwenden Sie einfach die bereits geladen eins (Dies wird möglicherweise öffnen bis zu ungeraden Fällen und Bugs, wenn sie eine viel ältere Version von jQuery verwenden, aber ich habe nicht viel Auswahl).

Was ich dachte, wäre ich schreibe ein neues Modul, das würde zuerst sehen, ob jQuery geladen ist, wenn ja, nur exportieren Sie das jQuery-Objekt, wenn es nicht ist, dann laden Sie es, dann den Export. Es scheint jedoch, dass ich behindert bin, da die Definitionsfunktion für das Modul synchron zur Arbeit zu sein scheint, so dass ich nicht loslegen und ein anderes Skript laden kann, das asynchron wäre, und dann den Export in requirej stopfen würde.

Fehle ich etwas in den Dokumenten? Ist das was ich versuche unmöglich?

+0

Wäre es hilfreich, [zwei verschiedene Versionen von jQuery gleichzeitig laden zu können] (http://stackoverflow.com/q/1566595/33732)? –

+0

Das würde die Versionierungsprobleme lösen. Dies scheint jedoch das Plugin-Trampling nicht zu lösen, da mehr als wahrscheinlich die On-Page-Version vor mir geladen wird und kein No-Conflict auf. Ich nehme an, ich könnte meine gediente Version von jQuery modifizieren, um die $/jQuery-Objekte nicht zu zertrampeln und mich selbst als Modul auszusetzen, aber ich würde das lieber als letzten Ausweg tun, da ich mich daran erinnern müsste, das zu machen ändern, wenn ich jQuery aktualisiere. –

+1

Das sollte nicht wichtig sein. Nur eine der Bibliotheken muss den Modus "Kein Konflikt" kennen.Wenn Sie bei Ihrer Kopie von jQuery 'noConflict' aufrufen, werden die Werte von' $ 'und' jQuery' von den Originalen wiederhergestellt, bevor Ihre Kopie geladen wurde. Plug-Ins, die die ursprüngliche Instanz verwendet haben, beziehen sich weiterhin darauf. Die ursprüngliche jQuery-Instanz wird davon ausgehen, dass es die einzige ist, die in Ordnung ist. –

Antwort

26

Ich hatte das gleiche Problem in einem ähnlichen Projekt mit require.js für eine Bibliothek, die auf Websites von Drittanbietern geladen werden soll. Sie können mein Ansatz here, aber hier ist die vereinfachte Version sehen:

// check for existing jQuery 
var jQuery = window.jQuery, 
    // check for old versions of jQuery 
    oldjQuery = jQuery && !!jQuery.fn.jquery.match(/^1\.[0-4](\.|$)/), 
    localJqueryPath = libPath + 'jquery/jquery-1.7.2.min', 
    paths = {}, 
    noConflict; 

// check for jQuery 
if (!jQuery || oldjQuery) { 
    // load if it's not available or doesn't meet min standards 
    paths.jquery = localJqueryPath; 
    noConflict = !!oldjQuery; 
} else { 
    // register the current jQuery 
    define('jquery', [], function() { return jQuery; }); 
} 

// set up require 
require.config({ 
    paths: paths 
}); 

// load stuff 
require(['jquery', ... ], function($, ...) { 

    // deal with jQuery versions if necessary 
    if (noConflict) $.noConflict(true); 

    // etc 

}); 

Wie Sie sehen können, das sieht für jQuery, und dann entweder definiert den „jquery“ -Modul als Wrapper für die bestehende Bibliothek, oder (wenn Es gibt keine jQuery oder wenn die vorhandene jQuery eine alte Version ist) lädt die Bibliothek spezifische jQuery mit noConflict.

Das funktioniert ziemlich gut. Der einzige Nachteil ist, dass Sie require() dynamisch in Ihrem Skript aufrufen, wodurch es schwieriger wird, den Optimierer r.js effektiv zu verwenden.

+0

Netter Code. Der oldjQuery-Regex funktioniert jedoch nicht für jQuery> = 1.10. – Chris

+1

Danke, @Chris - aktualisierte Regex. – nrabinowitz

+0

Ich habe eine ähnliche Frage hier http://stackoverflow.com/questions/20291793/adding-requirejs-module-that-uses-jquery-on-a-page-that-already-has-jquery-as-a. Wie verwenden Sie nicht eine "Map" wie in der API vorgeschlagen? Was würden Sie tun, wenn Sie eine dritte Version von jquery für ein anderes Modul laden möchten? – gillyspy

3

hatte ich ein ähnliches Problem .. Mein Skript jQuery wurde zweimal Nachladen .. die Lösung aus den Kommentaren verwendet in this article

wie ein Charme !!

(Kommentar, gearbeitet wurde:

"Ich habe es auf meine Config-Datei nach dem requirejs.config (...) und vor die requirej ([" app "]) und es funktionierte")

+1

Viel einfacher als die angenommene Antwort – LostInComputer

Verwandte Themen