200910Dez

jQuery-Tutorial: Dynamische Inhalte mit Ajax laden

Der Begriff "Dynamik" dürfte im Bereich der Webentwicklung viele Bedeutungen haben. Im Allgemeinen ist Dynamik mit Bewegung und Geschwindigkeit verbunden. Wenn man das auf eine Website bzw. eine Webanwendung überträgt, würde das auf der einen Seite das optische Erscheinungsbild (Effekte, Animationen) und auf der anderen Seite die Datenverarbeitung (HTML-Daten, Skriptsprachen, Benutzereingaben) betreffen. In diesem Workshop bezieht sich die Dynamik auf Daten, die im Hintergrund nachgeladen werden und die Seite beim Benutzer nicht aktualisiert werden muss. Dies wird durch Ajax ermöglicht. Bei Ajax (Asynchronous JavaScript and XML) handelt es sich nicht um eine Sprache, sondern um ein Konzept der asynchronen Datenübertragung. Durch JavaScript und der XMLHttpRequest-Schnittstelle (XHR) ist es möglich, Dokumente zu laden und deren Inhalt auf DOM-Elemente anzuwenden. Mehr darüber lässt sich bei Wikipedia nachlesen.
Ich habe versucht, die Ajax-Methode in einem einfachen Schaubild darzustellen:

Ajax mit XMLHttpRequest

Das HTTP-Protokoll versteht mehrere Anfragemethoden (z.B. GET, POST, HEAD, PUT). Statische Daten wie HTML-, CSS- oder Bilddateien werden mit der GET-Methode übertragen. Die GET-Methode kann zudem auch dazu genutzt werden, Variablen an eine dynamische Skriptsprache wie PHP zu übermitteln. Dies geschieht über Query-Strings, die allseits bekannt sein dürften:

  • datei.php?variable1=A&variable2=B

Leerstellen in Query-Strings werden automatisch in ein "+" umgewandelt, während andere Sonderzeichen (z.B. Umlaute) ebenfalls kodiert werden (URL-Enkodierung). Diese Thematik wird später im Tutorial benutzt.

In jQuery funktioniert natürlich alles mit einfachen Befehlen, so dass man sich auf das Design der Funktionalitäten kümmern kann. Dennoch gibt es verschiedene Möglichkeiten, Ajax-Anfragen in jQuery durchzuführen. Es ist nicht zwingend erforderlich, dynamische Dokumente (PHP, ASP, etc.) per Ajax zu laden — es können auch gewöhnliche Daten wie JavaScript-Dateien oder HTML-Dokumente geladen werden.
In diesem Tutorial will ich auf die Befehle eingehen, mit denen sowohl "GET"- als auch "POST"-Daten verarbeitet werden können. Für Kontaktformulare und Derartiges sollte "POST" verwendet werden, während Seitendarstellungen und spezifische Inhalte (Kategorien, Produkte, etc.) mit der "GET"-Methode realisiert werden sollten. Daher kommt PHP zum Einsatz und JS Bin eignet sich für die folgenden Beispiele ausnahmsweise nicht.
Alle für das Tutorial benötigten Dateien können als ZIP-Archiv heruntergeladen oder per Hand eingegeben werden. Für die Durchführung der Beispiele kann online (Server mit PHP-Unterstützung wird vorausgesetzt) oder offline mittels XAMPP gearbeitet werden.

Dieses Tutorial basiert auf 3 Dateien, die hier als Klartext angesehen werden:

Auf den Inhalt der Dateien werde ich nun eingehen. Editiert werden muss für dieses Tutorial lediglich die Datei "test.html", mit der ich beginnen will: Dem noch leeren script-Bereich der Datei werden wir nun alle jQuery-Beispiele hinzufügen. Die DOM-Elemente des Dokuments werden mit jQuery adressiert. Hier noch einmal die entscheidende HTML-Struktur der Datei:

  • <button id="ajaxloadlink">Lade ajax.php mit load()</button>
  • <button id="ajaxgetlink">Lade ajax.php mit get()</button>
  • <button id="ajaxpostlink">Lade ajax.php mit post()</button>
  • <button id="ajaxlink">Lade ajax.php mit ajax()</button>
  • <button id="ajaxscriptlink">Lade script.js mit getScript()</button>
  • <div id="ajaxcontent"></div>

Wie oben erwähnt, können Ajax-Inhalte auf DOM-Elemente angewendet werden. Ich werde später alle jQuery-Funktionen dazu nutzen, den Inhalt des div-Containers mit der ID "ajaxcontent" zu ändern. Dies wird durch die "html()"-Funktion von jQuery ermöglicht, mit der nur der Inhalt innerhalb eines HTML-Tags geändert wird — der umschließende Tag (Wrap, in diesem Fall div) bleibt erhalten.
Das Anpassen der CSS-Stile kann mit jQuery vorgenommen werden. Dazu muss folgender Code in den bestehenden "$(document).ready()"-Bereich eingefügt werden:

  • Quelltext
  • $("#ajaxcontent").css({
  • "width": 200,
  • "height": 200,
  • "border": "1px solid"
  • });
  •  
  • $("button").css({
  • "display": "block"
  • });

Bevor ich auf die erste Ajax-Funktion von jQuery eingehe, sollte noch eine Sache beachtet werden: Alle Funktionen können lediglich Daten per Ajax laden, die sich auf dem gleichen Server wie die ausführende JavaScript- bzw. HTML-Datei befinden. Eine Ausnahme bildet die Funktion "getScript()", die auch JavaScript-Dateien von anderen Servern laden kann. Dazu später mehr.

Die einfachste Methode, Inhalt aus einer Datei in ein DOM-Element zu laden, stellt die Funktion "load()" dar, die aufgerufen wird wie folgt:

  • $("element").load({
  • url,
  • data,
  • callback
  • });

Die Parameter "data" und "callback" sind optional — werden diese nicht angegeben, wird von jQuery ein einfacher Ajax-Request mit der "GET"-Methode erstellt. Das wird unser erstes Beispiel. Zur Erinnerung hier der Inhalt der Datei "ajax.php", die ich in allen Beispielen als "Zieldatei" einsetzen werde:

  • <?php
  • if ($_GET) {
  • echo $_GET["ajaxget"];
  • } else if ($_POST) {
  • echo $_POST["ajaxpost"];
  • } else {
  • echo "Direktaufruf oder load()-Daten (GET)";
  • }
  • ?>

Das kleine PHP-Skript überprüft ob "GET"- oder "POST"-Daten sowie entsprechende Variablen vorhanden sind und gibt beim Fehlen dieser Daten eine Standardnachricht aus. An den vorhandenen jQuery-Code im "$(document).ready()"-Bereich kann nun folgender Code angefügt werden:

  • Quelltext
  • $("#ajaxloadlink").click(function(){
  • $("#ajaxcontent").load("ajax.php");
  • });

Bei einem Klick auf den ersten Button mit der ID "ajaxloadlink" wird der Inhalt des div-Containers "ajaxcontent" per Ajax aktualisiert. Der Text "Direktaufruf oder load()-Daten (GET)" wird dargestellt.
Nun können auch Parameter bzw. Variablen übermittelt werden. Handelt es sich bei den Daten um "POST"-Daten, schaltet jQuery automatisch auf die "POST"-Methode um. Hier ein Beispiel:

  • Quelltext
  • $("#ajaxloadlink").click(function(){
  • $("#ajaxcontent").load(
  • "ajax.php",
  • {
  • ajaxpost: "post()-Daten (POST)"
  • }
  • );
  • });

Die Variable "ajaxpost" wird in unserem PHP-Skript definiert und dargestellt, sobald "POST"-Daten gesendet wurden. Das Ganze lässt sich übrigens sehr gut mit Firebug und dessen "Netzwerk"-Modul überprüfen.

Firebug - Netzwerk

Der dritte Parameter "callback" der "load()"-Funktion kann mit 3 Parametern (Argumenten) angesprochen werden:

  • function (responseText, textStatus, XMLHttpRequest){
  • // Code
  • }

Diese Parameter finden auch in weiteren Ajax-Funktionen von jQuery Verwendung und können zur Kontrolle oder spezifischen Manipulation von Ereignissen genutzt werden. Zum Testen kann die Callback-Funktion in unser Beispiel übertragen werden:

  • Quelltext
  • $("#ajaxloadlink").click(function(){
  • $("#ajaxcontent").load(
  • "ajax.php",
  • {
  • ajaxpost: "post()-Daten (POST)"
  • },
  • function (responseText, textStatus, XMLHttpRequest){
  • alert(
  • responseText + ", " +
  • textStatus + ", " +
  • XMLHttpRequest
  • );
  • }
  • );
  • });

Als Ausgabe würde man erhalten:

  • post()-Daten (POST), success, [object XMLHttpRequest]

Mit "load()" wird der geladene Ajax-Inhalt direkt auf den "html()"-Wert (Inhalt) des aufrufenden DOM-Objekts angewendet. Die weiteren Ajax-Funktionen laden lediglich die Daten im Hintergrund — möchte man den neuen Inhalt direkt auf ein DOM-Element anwenden, muss eine Callback-Funktion genutzt werden. Natürlich ist es nicht immer gewünscht, Daten als DOM-Inhalt auszugeben. Dies soll lediglich zum besseren Verständnis in diesem Tutorial dienen.

Die nächste Ajax-Funktion von jQuery nennt sich "get()" und ist ihrem Namen treu. Damit werden Daten mit der "GET"-Methode übermittelt. Im Hintergrund wird also eine Anfrage im Stil von "datei.php?variable=wert" ausgeführt. Hier der Code:

  • Quelltext
  • $("#ajaxgetlink").click(function(){
  • $.get("ajax.php",
  • {
  • ajaxget: "get()-Daten (GET)"
  • },
  • function(data){
  • $("#ajaxcontent").html(data);
  • }
  • );
  • });

Wie man sieht, gibt es kein Referenz-Element, das die Funktion aufruft: In Zeile 2 wird mit "$.get(…" eine globale Funktion aufgerufen, weshalb sich nach dem Laden der Ajax-Daten keine sichtbaren Ergebnisse zeigen würden. Dies bewerkstelligen wir mit der Callback-Funktion (Zeile 6-8), die den "html()"-Wert unseres Ajax-Containers mit der ID "ajaxcontent" manipuliert. Im Hintergrund wird also folgende Anfrage als XMLHttpRequest an den Browser geschickt:

  • ajax.php?ajaxget=get()-Daten+(GET)

Das Leerzeichen wurde automatisch in ein "+" konvertiert. Im Gegensatz zu "GET"-Daten werden die zu übertragenden Daten bei der "POST"-Methode nicht an die URL der aufrufenden Datei angehängt. Damit kommen wir zur nächsten Funktion, der "post()"-Funktionalität. Sie funktioniert genau wie die "get()"-Funktion und wird genutzt wie folgt:

  • Quelltext
  • $("#ajaxpostlink").click(function(){
  • $.post("ajax.php",
  • {
  • ajaxpost: "post()-Daten (POST)"
  • },
  • function(data){
  • $("#ajaxcontent").html(data);
  • }
  • );
  • });

Gesendete "POST"-Daten lassen sich wie oben erwähnt prima mit Firebug kontrollieren.

Eine Funktion, mit der sowohl "GET"- als auch "POST"-Anfragen gestellt werden können, ist die Methode "ajax()", die verschiedene Parameter und Einstellungen entgegen nimmt. Eine Anfrage könnte so aussehen:

  • Quelltext
  • $("#ajaxlink").click(function(){
  • $.ajax({
  • type: "GET",
  • url: "ajax.php",
  • data: "ajaxget=ajax()-Daten+(GET)",
  • success: function(data){
  • $("#ajaxcontent").html(data);
  • }
  • });
  • });

Die Callback-Funktion wird hier ausgeführt, sobald das "success"-Ereignis eintritt. Weiterhin ist beim Einsatz dieser Methode zu beachten, dass die "GET"- oder "POST"-Parameter von Hand konvertiert werden müssen (in diesem Fall das Leerzeichen). Die "ajax()"-Funktion kann wie gesagt mit etlichen Optionen aufgerufen werden, die sich in der Dokumentation nachlesen lassen.

Schließlich gibt es noch eine Ajax-Funktionalität in jQuery, mit der sich Skripte (JavaScript) aufrufen und direkt ausführen lassen: Die "getScript()"-Funktion. Dazu wird kein Callback benötigt, wenn die aufgerufene JavaScript-Datei bereits ausführbaren Code enthält. Dies ist in unserer Datei "script.js" der Fall:

  • $("#ajaxcontent").css({
  • "background": "yellow"
  • });

Damit wird der div-Container "ajaxcontent" beim Aufruf gelb eingefärbt. Im folgenden Beispiel habe ich zur Demonstration dennoch eine Callback-Funktion benutzt.

  • Quelltext
  • $("#ajaxscriptlink").click(function(){
  • $.getScript("script.js", function(){
  • $("#ajaxcontent").html("getScript() geladen.");
  • });
  • });

Bei "getScript()" kann als Ziel auch eine externe Datei im Stil von "http://www.domain.com/script.js" angegeben werden. Allerdings ist hier aufgrund von Cross-Site-Scripting (XSS) Vorsicht geboten, weshalb man die Quelle stets prüfen sollte.
Noch mehr Details und weitere Funktionen wie "getJSON()" können in der offiziellen jQuery-Dokumentation erforscht werden.

Die Zukunft von Ajax könnte die Web Sockets API sein, die den XMLHttpRequest ablösen würde, da sie schneller arbeitet und eine echte bidirektionale Verbindung darstellt. Googles Browser Chrome unterstützt die API in seiner aktuellen Entwicklerversion bereits. Man darf gespannt sein.