Das Problem ist bekannt: Webanwendungen die ihre zentralen Inhalte mittels Ajax-Technologie ändern, müssen zusätzlich dafür Sorge tragen, dass ihre dynamisch geänderten Inhalte ebenfalls in der URL-Leiste des Browsers referenzierbar bleiben. Diese Aufgabe muss auch von Flash-/Flex-Anwendungen durchgeführt werden. Wird im Flash-Plugin ein neuer Inhalt nachgeladen, ändert sich normalerweise nichts an der URL im Browserfenster. Somit gibt es ohne Eigeninitiative keine Möglichkeit direkt an den neu angezeigten Inhalt zu springen.
Die Lösung ist bekannt und an sich einfach. Wird mittels Ajax / Flex / Flash dynamisch ein neuer Inhalt angezeigt, muss mittels Java-Script die URL des Browsers entsprechend geändert werden. Der Haken dabei: der Browser lädt die Seite neu! Dies kann aber mit einem Trick verhindert werden.
Hier spielt das Hash-Zeichen (#) in der URL eine wichtige Rolle. Es dient zur Angabe eines Ankerpunktes (siehe W3C-Syntax of anchor names) in der aktuell angezeigten Webseite. Eine Ankerpunkt-Angabe gehört streng genommen nicht mehr zur URL, da sie nicht an den Web- / Applikationsserver gesendet wird. Der Browser versucht den mit dem Hash-Zeichen angegebenen Ankerpunkt innerhalb der aktuellen Seite zu finden und scrollt dann direkt an diesen Punkt. Findet der Browser keinen passenden Anker, bleibt die Position unverändert. Eine Webseite kann somit ein Inhaltsverzeichnis am Anfang präsentieren, deren Links nur reine Ankerwerte enthalten. Ein Klick auf solch einen Link sorgt dafür, dass der Browser an die Ankerstelle des gewünschten Kapitels springt. Dabei wird die Webseite nicht neu geladen. Und genau diesen Effekt macht man sich hier zu Nutze.
Wird der angezeigte Inhalt mittels Ajax oder in einer Flash-Anwendung aktualisiert, so muss der Ankerwert, welcher für den angezeigten Inhalt steht, mittels Java-Script in der URL angepasst werden. Hierfür gibt es zwei Möglichkeiten. Entweder man setzt den Wert in window.location.hash
oder man verwendet die Location-Methode window.location.Replace()
mit exakt der aktuellen URL, die nur am Ankerwert geändert wurde (unterscheidet sich die URL vor dem Anker-Hash von der aktuellen URL, startet der Browser eine neue Anfrage und lädt die entsprechende Seite nach!). Der Unterschied zwischen diesen beiden Möglichkeiten liegt in der Browser-History. Wird die URL mittels der Methode Replace()
ersetzt, wird die überschriebene URL-Angabe im Browser nicht als “besuchte Seite” vermerkt, was dazu führt, dass eine Navigation “zurück” mittels des Back-Buttons nicht möglich ist. Dies kann ein gewünschter Effekt sein, wenn eine Anwendung ohne die Browser-Navigations-Buttons arbeiten, aber Bookmarking unterstützen will.
Da der Web- / Applikationsserver bei einer Anfrage der Art http://somedomain.com/path/to/site/#document-id
nur die Angabe http://somedomain.com/path/to/site/
vom Browser zugesendet bekommt, also keine Anker-Angaben, muss mittels Ajax oder Flash/Flex (für Flex siehe: Accessing Flex from Javascript und Accessing Javascript from Flex) zu Beginn zusätzlich eine neue Anfrage für den Dokumenten-Inhalt gestartet werden. Hierzu wertet ein Java-Script nachdem die Webseite eingeladen wurde (Event-Funktion in window.onload
) den Inhalt von window.location.hash
aus und ruft die entsprechende Nachlade-Funktion für Ajax oder in einer Flash-Anwendung auf. Die Adresse könnte dafür beispielsweise http://somedomain.com/path/to/document/document-id
/ lauten. Diese Aktion muss ein Javascript auch dann durchführen, wenn sich durch den Back-Button oder durch eine “seiteninterne” Navigation der Anker-Wert änderte. Um diese Änderungen zu überwachen bietet es sich an, einen Timer zu implementieren, der in regelmäßigen Abständen überprüft, ob die URL im Browser noch zu dem aktuell angezeigten Inhalt passt. Wenn nicht, wird hier wieder per Ajax-Request bzw. innerhalb der Flash-/Flex-Anwendung der Inhalt angepasst. Eine detaillierte Beschreibung zu diesem “Ajax-Pattern” kann unter ajaxpatterns.org nachgelesen werden. Hier findet man auch passende Codebeispiele.
(updating url for bookmarking AJAX or Flash applications using the anchor syntax)
MRZ