Mehrere jQuery-Versionen gleichzeitig nutzen

jQuery bietet durch den noConflict-Modus von Haus aus die Möglichkeit, mehrere Versionen von jQuery bzw. jQuery zusammen mit anderen Libraries gleichzeitig zu nutzen. Den Overhead durch die Nutzung zweier gleichartiger Libraries sollte man tunlichst vermeiden. Leider ist man durch die Nutzung eines CMS unter Umständen gezwungen eine weitere Bibliothek einzubinden, ohne die alte anzutasten. In diesem Artikel erkläre ich Euch, wie das vonstatten gehen kann und welche Eigenheiten man beachten muss.

Einbinden und Sandboxen der Libraries

Wir geben hier einmal davon aus, dass wir neben der Version 1.3.2 von jQuery auch noch die aktuelle Version 1.8.2 einbinden wollen. Um die Eigenheiten dieser doppelten Einbindung zu verdeutlichen, werden wir beide Libraries mit der noConflict-Methode sandboxen. Streng genommen ist dies allerdings nur für eine der Libraries notwendig. Die zuletzt eingebundene Bibliothek kann auch ohne noConflict weiterverwendet werden.


<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript">
  var jQuery132 = $.noConflict(true);
</script>

<script type="text/javascript" src="jquery-1.8.2.min.js"></script>
<script type="text/javascript">
  var jQuery182 = $.noConflict(true);
</script>   

Wir binden hier jeweils die entsprechende Bibliothek ein und geben das so registrierte $-Zeichen anschließend sofort wieder frei. Stattdessen weisen wir der Bibliothek eine selbst definierte Variable zu, über die wir diese später ansprechen können.

Wollen wir nun eine der Bibliotheken verwenden, müssen wir das Dollarzeichen zuvor wieder für diese Bibliothek registrieren. Dies können wir durch "Sandboxen" erreichen. Innerhalb unseres Wrappers wird das Dollarzeichen automatisch nur für die von uns gewählte Library verwandt. In diesem Fall ist dies die Version 1.8.2.


(function($) {
  // Your code goes here...
})(jQuery182);

Jede Bibliothek kennt nur Ihre eigenen Events

Wie der Begriff Sandboxen schon suggeriert, werden die beiden Libraries völlig voneinander abgeschottet. Definieren wir also beispielsweise einen Event in der einen Sandbox, so weiß die andere davon überhaupt nichts. Im folgenden Beispiel gehe ich von einem vorhandenen Select auf der Seite aus.


(function($) {
  $(document).ready(function() {
    $('select').change(function() {
      alert('jQuery 1.8.2');
    });
  });
})(jQuery182);

(function($) {
  $(document).ready(function() {
    // Nothing happens...
    $('select').trigger('change');
  });
})(jQuery132);
    

Will man Events aus einer anderen Library aufrufen, so muss man diese direkt über die von uns zu Beginn definierte Variable aufrufen. Verändern wir das Beispiel wie folgt, so kann der Event über die Grenzen der Sandbox hinaus getriggert werden.


(function($) {
  $(document).ready(function() {
    // Alert: jQuery 1.8.2
    jQuery182('select').trigger('change');
  });
})(jQuery132); 
    

Verschachtelungen sind möglich, sollten aber vermieden werden

Tatsächlich ist es sogar möglich, Sandboxen beliebig ineinander zu verschachteln. Folgender Code funktioniert einwandfrei, ist allerdings nur schwer verständlich. Darum sollte so ein Konstrukt tunlichst vermieden werden.


(function($) {
  $('select').change(function() {
    alert('jQuery 1.8.2');
  });

  (function($) {
    $('select').change(function() {
      alert('jQuery 1.3.2');
    });   

    // Alert: jQuery 1.3.2
    $('select').trigger('change');
  })(jQuery132);

  // Alert: jQuery 1.8.2
  $('select').trigger('change');
})(jQuery182);
    

Ich hoffe ich konnte die Mysterien um den noConflict-Modus ein wenig lüften und dem einen oder anderen weiterhelfen.

Update 23.06.2013:

Vorsicht mit dem Parameter von noConflict. Wenn Ihr diesen auf true setzt, werden alle Referenzen auf jQuery entfernt. Auch die Variable jQuery selbst. Viele Plugins verwenden aber einen Wrapper der ungefähr so aussieht:

(function($) {
  $.fn.myPlugin(function() {
    // plugin code
  });
})(jQuery); 

Da Ihr jQuery aus dem globalen Namensraum entfernt, müssen die Plugins auf jeden Fall vor Eurem noConflict-Aufruf eingebunden werden. Ungefähr so:

<script src="jquery.0.8.15.js"></script>
<script src="myplugin.js"></script>
<script>// noConflict</script>
    

Ihr solltet also immer in dieser Reihenfolge einbinden:

  1. jQuery-Version
  2. Plugins für diese Version
  3. noConflict
  4. nächste jQuery-Version
  5. Plugins für die nächste Version