Bessere verlinkbare Tabs

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Ich finde, dass es bei „Tab“-Designmustern oft der Wunsch besteht, dass es eine Möglichkeit gibt, auf bestimmte Tabs zu verlinken. Das heißt, man könnte jemandem eine URL geben und diese URL würde ihn zu dieser Seite mit dem spezifischen gewünschten Tab führen, der aktiv ist und den korrekten Inhalt anzeigt.

Wenn jeder Tab eine komplett andere URL ist, ist das einfach. Im ausgelieferten HTML wird der entsprechende Klassenname dem Tab zugewiesen, damit er aktiv aussieht, und der entsprechende Inhalt darunter wird ausgeliefert.

Wufoo verwendet ein Tab-Designmuster in der App. Jeder Tab ist eine komplett andere Seite und URL.

Wenn diese Tabs „Same-Page“-Tabs sind, die sofort (oder über Ajax) verschiedene Inhaltsbereiche ein-/ausblenden, ist es etwas schwieriger. Ein gängiger (und meiner Meinung nach semantischer) Ansatz dafür sind Hash-Links, z. B.

http://example.com/#tab-three
Tabs wie diese sind wahrscheinlich „Same-Page“-Tabs, die keine eindeutigen URLs für sich selbst haben

Mit CSS3's :target Pseudo-Klassen-Selektor gibt es Möglichkeiten, funktionale Tabbed-Bereiche nur mit CSS zu erstellen (ohne JavaScript). Wenn reine CSS-Tabs das Ziel sind, ist dies besser.

So sehr ich auch mit CSS-Techniken experimentiert habe, glaube ich, dass funktionale Tabbed-Bereiche am besten durch JavaScript realisiert werden. Dies ist ein Funktionalitätsbereich, und wenn wir uns an das traditionelle Modell der Trennung von Belangen halten, sollte er von JavaScript behandelt werden.

Hash-Links haben einige andere Probleme

  1. Wenn die Seite mit einem Hash-Link geladen wird *oder* sich die Hash-Links ändern, scrollt der Browser **nach unten**, sodass das Element mit der ID dieses Hashs oben auf der Seite ist. Es ist sehr wahrscheinlich, dass dies nicht erwünscht ist. Letzteres lässt sich leicht mit preventDefault() bekämpfen. Ersteres ist fast unmöglich sauber zu handhaben.
  2. Das Ändern des Hash-Tags einer Seite fügt einen Eintrag in den Browserverlauf ein, sodass das Drücken der **Zurück-Taste** zu früheren Hashes zurückführt. Es ist auch sehr wahrscheinlich, dass dies nicht erwünscht ist.

Lösen wir beide Probleme und erfüllen gleichzeitig den Wunsch, eine Möglichkeit zu haben, auf einen bestimmten Tab zu verlinken. Das werden wir tun

  1. Keine Hash-Links verwenden, sondern URL-Parameter (kein Herunterspringen).
  2. Verwenden Sie das ultra-coole history.replaceState(), damit wir die URL ändern können, ohne den Zurück-Button zu beeinträchtigen.

Unsere URLs werden so aussehen

http://example.com/?tab=tab-three

Anstatt JavaScript-basierte Tabs von Grund auf neu zu schreiben, verwenden wir meine vorhandene Organic Tabs Demo. Wir müssen nur sehr wenig am Plugin ändern, damit dies funktioniert. Wir fügen einen Parameter hinzu, damit die Leute wählen können, was immer sie dort wollen.

$.organicTabs.defaultOptions = {
    "speed": 300,
    "param": "tab"
};

Dann fügen wir im Teil mit der gesamten Tab-Wechselfunktionalität diese eine Zeile hinzu

// Change window location to add URL params
if (window.history && history.pushState) {
  // NOTE: doesn't take into account existing params
	history.replaceState("", "", "?" + base.options.param + "=" + listID);
}

Das knifflige ist, dass wir den URL-Parameter beim Laden der Seite abrufen und damit JavaScript-Sachen machen müssen. Das bedeutet, dass wir eine serverseitige Sprache verwenden und etwas davon mit unserem JavaScript vermischen müssen. Hier verwende ich PHP

Update: Wir können auf die gesamte Query-String über JavaScript zugreifen und die Teile einfach parsen. Anstatt des PHP, das hier früher stand (aus vielen Gründen nicht ideal), machen wir stattdessen Folgendes

var queryString = {};
window.location.href.replace(
    new RegExp("([^?=&]+)(=([^&]*))?", "g"),
    function($0, $1, $2, $3) { queryString[$1] = $3; }
);

if (queryString[base.options.param]) {

	var tab = $("a[href='#" + queryString[base.options.param] + "']");

	tab
		.closest(".nav")
		.find("a")
		.removeClass("current")
		.end()
		.next(".list-wrap")
		.find("ul")
		.hide();
	tab.addClass("current");
	$("#" + queryString[base.options.param]).show();
      
};

Dieser Code greift auf den URL-Parameter zu und stellt sicher, dass der aktuelle Tab hervorgehoben ist und der richtige Inhalt angezeigt wird.

Funktionale Demo

Demo ansehen   Dateien herunterladen

Video

Unvollständig-ish

Die Browserunterstützung für history.replaceState (und alle Browserverlaufsverwaltungsfunktionen) ist bei weitem nicht allgegenwärtig. Ich verwende hier einen einfachen Feature-Test, implementiere aber keinen Fallback. Der wichtige Teil, die Tab-Funktionalität, funktioniert weiterhin einwandfrei. Sie möchten vielleicht mehr tun.

Ich berücksichtige auch keine vorhandenen URL-Parameter. Wenn Ihre Seite diese bereits verwendet und Sie dies ebenfalls tun möchten (z. B. ?foo=bar&tab=tab-one), wird dies etwas komplizierter. Sie würden wahrscheinlich den gesamten URL-Param-String abgreifen und ihn an das Plugin übergeben. Dann parsen Sie ihn und fügen die vorhandenen Parameter wieder ein, wenn Sie replaceState() verwenden.