Anzeige
Anzeige
UX & Design

JQuery-Lösungen für typische Ajax-Probleme: Ajax mit jQuery meistern

Die Verwendung von Ajax in Webapplikationen und Webseiten stellt Frontend-Entwickler vor neue Herausforderungen in der JavaScript-Entwicklung. Dieser Artikel zeigt am Beispiel von jQuery einige Lösungsmuster für typische Probleme.

5 Min.
Artikel merken
Anzeige
Anzeige

jQuery bietet für die Verwendung von Ajax die Methode $.ajax an. Daneben existieren einige Methoden wie beispielsweise $.getJSON, $.get und andere, die vorkonfigurierte Varianten der Ajax-Methode darstellen sowie Ajax-Events wie „ajaxSuccess“ oder „ajaxComplete“ zur zentralen eventbasierten Ajax-Behandlung.

Anzeige
Anzeige

Mit Ajax kommen zur allgemein üblichen DOM-Script-Entwicklung einige weitere Herausforderungen hinzu:

  • Zusätzliche Fehlerquellen: Mit Ajax kommen möglicherweise zusätzliche Fehler wie http-, Format- und Timeout-Fehler ins Spiel
  • Ajax läuft grundsätzlich asynchron ab, was letztendlich dazu führt, dass Entwickler ihre Programme nicht linear coden können, sondern auf Events oder Callbacks warten müssen
  • Ajax führt meist zu DOM-Updates, die in der Regel nicht vom allgemeinen Initialisierungscode erfasst werden und die Komplexität des Skripts steigern können

jQuery sammelt alle möglichen Ajax-Fehler und führt, sofern konfiguriert, den error-Callback aus beziehungsweise triggert das ajaxError-Event mit weiteren Informationen zum Fehler. In dem Bestreben, möglichst schnell zum Ziel zu kommen, fangen viele Entwickler mit der Behandlung der erfolgreichen Abarbeitung des Ajax-Requests an. Kommt es zu Fehlern, fällt die Ursachenforschung allerdings schwer.

Anzeige
Anzeige

Dabei muss das Skript zum Loggen von Ajax-Fehlern gar nicht zeitraubend sein. Die Ausgabe von Fehlermeldungen benötigt hier weder eine schöne Oberfläche noch wiederkehrende Arbeit. Entwickler können sie einmal schreiben und dann in jedem Projekt wiederverwenden.

Anzeige
Anzeige
Einfaches Ajax-Fehlerlogging
$(document).ajaxError(function(e, xhr, opts, err){
	var status = (xhr || {}).status;
	xhr = null;
	setTimeout(function(){
		throw(e.type +' | '+ status +' | '+ opts.url);
	}, 0);
});

Listing 1

Der Error-Eventhandler zeigt die wichtigsten Informationen bei Auftreten eines Fehler in der Fehlerkonsole an. Das verwendete „setTimeout“ führt dazu, dass die Ausführung des übrigen Codes nicht durch „throw“ unterbrochen wird. Die Referenz auf das Ajax-Objekt wird per Hand gelöscht, um Memory Leaks im Internet Explorer zu vermeiden. Der Eventhandler lässt sich in Formatierung und Umfang weiter an die eigenen Bedürfnisse anpassen (Auswertung von opts.data/err). Ist das Logging-Script für Ajax-Fehler fertig, kann man ersten Request absetzen.

Fehler im Eventhandler finden

In der Regel führen click- oder submit-Events zur Ausführung von Ajax-Requests. Kommt es hierbei zu Fehlern, wird die default-Aktion des Browsers ausgeführt und der Fehler erscheint nur für einen Bruchteil einer Sekunde in der Konsole.

Anzeige
Anzeige

Eine Möglichkeit, die default-Ausführung trotz Fehler zu verhindern, bietet der Aufruf der Methode „preventDefault“ (siehe Listing) bereits ganz am Anfang des Eventhandlers auf dem Event-Objekt. Dies ist zumindest im Live-Betrieb keine gute Idee. Tritt nämlich unerwartet ein Fehler auf, passiert aus Nutzersicht schlichtweg nichts. Führt man die Methode dagegen am Ende aus oder bricht die default-Aktion mit „return false“ ab, fällt die Webseite im Fehlerfall und bei sauberer unobtrusiver Programmierung [1] automatisch auf das Ajax-Fallback zurück. Die Webanwendung wird damit auf elegante Weise fehlertolerant.

preventDefault
$('a').click(function(e){
	e.preventDefault();
});

Listing 2

Wesentlich geschickter ist es daher, den verwendeten JavaScript-Debugger so einzustellen, dass er bei Fehlern selbstständig stoppt beziehungsweise die Fehlerkonsole beim Wechsel der Seite nicht leert. Beides kann man in Firebug entsprechend einstellen. Im IE-Debugger ist dies bereits Default.

Animationen und Userfeedback

Mit der Latenz zwischen Ajax-Request und -Response geht einher, dass der User darüber informiert werden sollte, dass seine Interaktion gerade verarbeitet wird. Animationen gehören hierbei zu einer eleganten Möglichkeit, den „Busy“-Status der Webseite deutlich zu machen. Soll beispielsweise der alte Inhalt ausgefadet und dann der neue Content wieder eingefadet werden, steht man vor der Herausforderung, dass die genaue Dauer der Ajax-Verarbeitung nicht vorhergesagt werden kann. Erfolgt die Server-Antwort bereits nach sehr kurzer Zeit und wird dann der neue Content sofort eingefügt, kann der User den Inhaltswechsel bereits vor Ablauf des Fade-out-Effekts sehen, wodurch die Animation recht hölzern wirkt.

Anzeige
Anzeige

jQuery bietet zur Lösung dieses Problems die queue-Methode auf DOM-Ebene an. Mit der queue-Methode können Funktionen in eine Warteschlange gebracht werden, sodass sie erst nach vollständigem Ablauf der Animation aufgerufen werden. Mit „dequeue“ kann die Funktion wieder aus der Warteschlange entfernt werden, was wiederum die nächste in der Warteschlange befindliche Funktion aufruft.

Animations-/Success-Queue
//Event-Hanlder löst Ajax-Request aus
myApp.requestUrl = function(e){
	$('#main').fadeTo(400, 0)
		.parent().addClass('busy')
	;
	$.ajax({
		url: this.href,
		dataType: 'html',
		success: myApp.onSuccess
	});
	return false; //oder e.preventDefault();
};
//success-Handler
myApp.onSuccess = function(content, status){
	$('#main').queue(function(){
		$(this)
			.html(content).fadeTo(400,1).dequeue()
			.parent().removeClass('busy')
		;
	});
};

Listing 3

Nachgeladenes DOM „re-enhancen“

Wird HTML nachträglich verändert, wirken die bei der Initialisierung hinzugefügten Eventhandler und angewendeten DOM-Manipulationen nicht auf das neue HTML. Vielmehr muss das neue HTML nochmals „jQueryfiziert“ werden. Eine Ausnahme sind Eventhandler, die mit der Methode „live“ hinzugefügt wurden. Muss der Initialisierungscode ausschließlich Eventhandler hinzufügen, kann man bei einer Ajax-Webseite demnach auf diese Methode zurückgreifen [2]. Muss der Initialisierungscode dagegen ebenfalls verschiedene DOM-Manipulationen übernehmen, empfiehlt sich ein eventgetriebener Ansatz mit custom-Events.

Hierbei wird der Code in mindestens zwei Teile geteilt. Der eine Teil übernimmt die normale Initialisierung und der andere wird praktisch mit jedem DOM-Update neu ausgeführt. Hierzu wird ein custom-Listener hinzugefügt, der sowohl initial als auch durch die Ajax-Success-Methode(n) getriggert wird. Durch diesen Aufbau können sich verschiedene JavaScript-Module bei Bedarf in DOM-Updates einklinken oder über solche informieren, ohne Abhängigkeiten zwischen den Modulen zu erzeugen.

Anzeige
Anzeige
Möglicher Initialisierungscode bei Ajax-Seiten
myApp.init = function(){
	//normaler init-code
	//Binden und erstes Ausführen des DOM-Change codes
	$(document).bind('HTMLchange', myApp.domChange);
	$.event.trigger('HTMLchange');
};
myApp.domChange = function(e){
	//e.target referenziert immer das Element, welches getriggert wurde
	var context = e && e.target || document;
	$('div.tabs', context).tabs();
};
//starten von init bei DOMREADY
$(myApp.init);

Listing 4

Sobald die onSuccess-Methode das neue HTML ins DOM einfügt, kann das custom-Event „HTMLchange“ am #main-Element getriggert werden. Da auch custom-Events den DOM-Baum nach oben bubbeln, erreichen sie das document-Objekt. Die target-Eigenschaft referenziert hierbei das #main-Element als Ursprungselement, so dass nur nach neuen div.tabs-Elementen gesucht wird, um hierauf nun die Aktionen auszuführen.

Ajax ist asynchron, so dass Requests nicht in der selben Reihenfolge abgearbeitet werden, wie sie abgeschickt wurden und auch nicht in der selben Reihenfolge wieder beim Client ankommen. Daher sollte man vorher entscheiden, ob es auf Reihenfolge und Synchronität ankommt. Ist dies der Fall, können diverse Ajaxmanager [3] und Ajaxqueues [4] helfen. Das Pluginrepository von jQuery [5] bietet hier eine große Auswahl.

Ajax und Barrierefreiheit

Eine weitere Hürde bei Ajax stellt die Zugänglichkeit dar. Assistive Technologien wie Screenreader müssen über HTML-Änderungen gesondert informiert werden, damit sie diese Inhalte vorlesen können. Kleinere HTML-Änderungen ohne Interaktionsinhalt, wie beispielsweise eine Änderung eines Warenkorbs, können durch die Aria-Liveregionen zugänglich gemacht werden [6]. Hierbei wird einfach das HTML-Element, dessen Inhalt sich ändert, mit dem Attribut „aria-live=“polite““ versehen. Hierdurch wird bei einer DOM-Änderung dieses Bereichs der neue Inhalt vorgelesen, ohne dass der Nutzer seinen aktuellen Ort/Fokus in der Seite ändert.

Anzeige
Anzeige

Bei größeren Bereichen und jenen, in denen Interaktionselemente wie Links oder Formulare vorhanden sind, sollte mit der DOM-Methode „focus“ die aktuelle Position im Dokument verschoben werden [7]. Die focus-Methode sollte hierbei innerhalb der setTimeout-Methode erfolgen. Nativ nicht fokusierbare Elemente können mit dem tabindex-Attribut fokusierbar gemacht werden.

vollständiger onSuccess-Handler
//success-Handler
myApp.onSuccess = function(content, status){
	$('#main').queue(function(){
		$(this)
			.html(content).fadeTo(400,1).dequeue().trigger(' HTMLchange')
			.parent().removeClass('busy')
			//Vorsicht: focus(1) ist ein a11y-Feature von jQuery UI,
			//welches setTimeout verwendet
			.find(':header:first').attr('tabindex', '-1').focus(1)
		;
	});
};

Listing 5

Mehr zu diesem Thema
Fast fertig!

Bitte klicke auf den Link in der Bestätigungsmail, um deine Anmeldung abzuschließen.

Du willst noch weitere Infos zum Newsletter? Jetzt mehr erfahren

Anzeige
Anzeige
Schreib den ersten Kommentar!
Bitte beachte unsere Community-Richtlinien

Wir freuen uns über kontroverse Diskussionen, die gerne auch mal hitzig geführt werden dürfen. Beleidigende, grob anstößige, rassistische und strafrechtlich relevante Äußerungen und Beiträge tolerieren wir nicht. Bitte achte darauf, dass du keine Texte veröffentlichst, für die du keine ausdrückliche Erlaubnis des Urhebers hast. Ebenfalls nicht erlaubt ist der Missbrauch der Webangebote unter t3n.de als Werbeplattform. Die Nennung von Produktnamen, Herstellern, Dienstleistern und Websites ist nur dann zulässig, wenn damit nicht vorrangig der Zweck der Werbung verfolgt wird. Wir behalten uns vor, Beiträge, die diese Regeln verletzen, zu löschen und Accounts zeitweilig oder auf Dauer zu sperren.

Trotz all dieser notwendigen Regeln: Diskutiere kontrovers, sage anderen deine Meinung, trage mit weiterführenden Informationen zum Wissensaustausch bei, aber bleibe dabei fair und respektiere die Meinung anderer. Wir wünschen Dir viel Spaß mit den Webangeboten von t3n und freuen uns auf spannende Beiträge.

Dein t3n-Team

Melde dich mit deinem t3n Account an oder fülle die unteren Felder aus.

Bitte schalte deinen Adblocker für t3n.de aus!
Hallo und herzlich willkommen bei t3n!

Bitte schalte deinen Adblocker für t3n.de aus, um diesen Artikel zu lesen.

Wir sind ein unabhängiger Publisher mit einem Team von mehr als 75 fantastischen Menschen, aber ohne riesigen Konzern im Rücken. Banner und ähnliche Werbemittel sind für unsere Finanzierung sehr wichtig.

Schon jetzt und im Namen der gesamten t3n-Crew: vielen Dank für deine Unterstützung! 🙌

Deine t3n-Crew

Anleitung zur Deaktivierung
Artikel merken

Bitte melde dich an, um diesen Artikel in deiner persönlichen Merkliste auf t3n zu speichern.

Jetzt registrieren und merken

Du hast schon einen t3n-Account? Hier anmelden

oder
Auf Mastodon teilen

Gib die URL deiner Mastodon-Instanz ein, um den Artikel zu teilen.

Anzeige
Anzeige