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.

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

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
- 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. - 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
- Keine Hash-Links verwenden, sondern URL-Parameter (kein Herunterspringen).
- 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.
Hey Mann, du hast zwei Links „Demo anzeigen“.
Der zweite muss wohl „Dateien herunterladen“ sein.
Entschuldigung für mein schlechtes Englisch
lese dich seit 3 Jahren
Cheers =)
Behoben und Kommentar verbergen, da er jetzt irrelevant ist. Danke!
Chris, überprüfe die Tab-Variable
oder erstelle einfach eine neue Variable
Ich sehe keinen Grund, warum du den Anfangswert des URL-Parameters nicht aus JavaScript statt aus PHP beziehen könntest. Vor allem, da dies in externen JS-Dateien stehen sollte ;)
Ich bin neulich auf diesen Schnipsel gestoßen, er könnte brauchbar sein: http://stevenbenner.com/2010/03/javascript-regex-trick-parse-a-query-string-into-an-object/
Vielleicht könntest du in Erwägung ziehen, dass das Tab-Plugin diese Dinge beim Initialisieren erledigt und vielleicht die URL-Abfrage so aussieht
?tabId=tab-1&tabIdTwo=tab-2
Wobei tabId und tabIdTwo die #IDs der Elemente sind, auf denen das Tab-Plugin ausgeführt wird? So kannst du mehrere Tab-Steuerelemente auf einer Seite haben und die URL-Sache funktioniert trotzdem :) Nur eine Idee ;)
Nebenbemerkung: Bitte versuchen Sie, immer sicheren Code zu schreiben, auch wenn es sich nur um ein Proof of Concept handelt. Leute werden Ihren Code kopieren und einfügen, ohne die Sicherheitsimplikationen zu verstehen. (Anton, das gilt auch für Ihren Code.)
Probieren Sie dies
Hier ist etwas XSS für dich
Noch ein Grund, kein PHP dafür zu verwenden, wenn JS ausreicht :)
Der einzige Grund, serverseitiges Skripting dafür zu verwenden, ist, wenn der Inhalt der Tabs mit Ajax geladen wurde und Sie den Inhalt des ausgewählten Tabs aus SEO-Gründen im Code ab dem Laden anzeigen möchten. Aber die Auswahl des Tabs selbst könnte immer noch in JS erfolgen.
Jeppe, ich stimme zu.
Was XSS angeht, ist reines PHP ein ziemlicher Albtraum. Natürlich kann man auch mit Javascript Dinge vermasseln. :)
Ich habe das gesamte PHP entfernt und es zu reinem JavaScript gemacht. Dank Jeppe für diese nette Funktion, um den Query-String einfach zu erhalten.
Natürlich ist die Verwendung von JavaScript anstelle von PHP (oder anderer serverseitiger Technologie) keine Garantie gegen XSS-Probleme. Ich glaube, dass dieses Beispiel anfällig für einen ähnlichen Angriff wäre, wenn es nur eine Monat alte Version 1.6.2 von jQuery verwenden würde.
Ich mochte die Idee, die Sie für die Zurück-Taste verwendet haben, die Idee von
history.replaceState();. Davon wusste ich nichts. Allerdings glaube ich nicht, dass das Vorhandensein von Hash-Links (Fragment-Identifikatoren in Links) aus der Benutzersicht schlecht ist. Stack Overflow hat diese Technik an vielen Stellen verwendet und ich habe sie fast nirgendwo kritisiert gesehen.Ich werde dazu eine Frage bei User Experience vom Stack Exchange Netzwerk stellen.
Danke.
In Google+ laden Tabs fast augenblicklich (als ob sie Teil derselben Seite wären), aber wenn ich auf andere Tabs klicke, ändert sich die URL sofort zu einer anderen und es sind keine Parameter beteiligt.
Beispiel
Ich bin auf plus.google.com/103982534066/about
Dann klicke ich auf den Button „Bilder“.
Dann ändert sich die URL sofort zu plus.google.com/103982534066/pictures und einige Bilder werden angezeigt (der Tab wird sofort „aktiviert“).
Und ich habe keine 400 Gbit/s Verbindung.
Wie wird das gemacht?
normalerweise mache ich dafür einfach jQuery und mache eine addClass // removeClass Funktion beimonClick, so habe ich es zumindest hier bei meinem Job gemacht, wo die Entwickler PHP hassen, lol.
Ich bin mir nicht sicher, ob ich es auf andere Weise tun sollte oder ob es einen Grund gibt, dies anders zu tun.
Aber, und die anderen Browser, die
history.replaceState()nicht unterstützen?Ich liebe die Art und Weise, wie Sie Themen immer wieder aufgreifen. So lerne ich auch und schätze Ihren Prozess sehr.
Sie erwähnten, dass ein Problem mit der Hash-Lösung darin besteht, dass der Browser nach unten scrollt, sodass das Element mit der ID sichtbar ist. Ich habe festgestellt, dass, wenn ich ein Shebang #! verwende, dies das Scrollen verhindert und ein zweiter Vorteil darin besteht, dass es eine Grundlage für Google-freundliche AJAX-Tabs schafft.
Sie können einen Hash-Link verwenden, der *nicht* die ID des Tabs ist. Zum Beispiel könnten Sie nur dem Wrapper-Element eine ID wie
tab-listgeben und dann einen Hash-Link wie#tab-list-3für den 3. Tab verwenden. Oder vielleichtdata-Attribute verwenden?Tabs funktionieren großartig, unglaubliche Arbeit!
Das Einfügen der Query-String in die Seite mit JavaScript öffnet die Seite immer noch für die Verwendung eines selbstreferenziellen IFRAME-XSS-Angriffs, wie im untenstehenden Dokument aufgeführt. Das Problem muss auf Browser-Ebene gelöst werden, nicht auf Site-Ebene.
https://sitewat.ch/files/Bypassing%20Internet%20Explorer's%20XSS%20Filter.pdf
Wieder ein großartiges Tutorial, danke.
Aber ich denke, es ist wichtig zu erwähnen, dass alle aktuellen IE-Versionen
history.replaceState()nicht unterstützen und daher diese Lösung für professionelle Websites nur begrenzt sinnvoll ist.IE10 wird die Funktion unterstützen... aber wenn ich bedenke, wie viele Benutzer meine Websites immer noch mit IE7 besuchen, werde ich noch 10 Jahre warten müssen, um sie zu nutzen :)
Das habe ich erwähnt.
Es funktioniert nicht im Opera-Browser, was machen wir dann?
Sie müssen etwas falsch gemacht haben, Mann, ich benutze Opera und es funktioniert einwandfrei.
Was das angeht, muss ich immer noch einen guten Verwendungszweck für diese großartige Ersetzung finden, vielleicht in einem internen Menü, ich habe immer noch keine Ahnung, wie ich es für die Seitennutzung einreichen soll.
Ich würde gerne Ihre Ideen hören, wie man diese Funktion nutzt... abgesehen von den im Tutorial genannten Optionen.
Wenn man history.replaceState() verwendet, wird dann in Analytics getrackt, welche Tabs angesehen wurden? Ich glaube nicht, dass das #-Tag in GA als separate Seite erfasst wird (vielleicht habe ich es noch nicht gefunden). Denn wenn man es aus der Datenaufzeichnungsperspektive betrachtet, sind Tabs nicht gut, wenn man nicht verfolgen kann, welche Tabs die Leute angesehen haben.
Ich bin zufällig auf diesen Beitrag gestoßen.
Ich suchte ursprünglich nach etwas anderem und der Artikel war so informativ, dass ich auf Ihre Homepage ging, um zu sehen, worüber Sie sonst noch sprachen. Ich war begeistert, Ihre hilfreichen Informationen zu linkbaren Tabs zu finden – es scheint im Moment sehr wenig darüber geschrieben zu werden.
Ein Problem, mit dem ich kämpfe: Formular vs. Funktion. http://www.example.com/#reports fühlt sich für mich „besser“ an als „http://www.example.com/?tab=reports“ – besonders aus der Perspektive des Endbenutzers.
Nichtsdestotrotz, ein großartiger Artikel und eine großartige Seite im Allgemeinen.
Sie können den Konstruktor
new RegExpdurch ein Literal ersetzen:/([^?=&]+)(=([^&]*))?/g, was meiner Meinung nach viel sauberer ist als die Verwendung des Konstruktors.Gute Arbeit
Ich lechze nach dem Tag, an dem wir das nur mit CSS machen können.
Aber es ist immer noch jQuery für mich im Moment.....
Vielen Dank,
David
Hallo,
Ich habe nach einem guten Tab-bezogenen Thema gesucht und dieses hier gefunden, das großartig ist.
Zuerst einmal vielen Dank für die Erstellung solch großartiger und einfacher jQuery-Tabs.
Zweitens möchte ich eine Frage stellen.
Entschuldigung für meine Unwissenheit.
Ich habe 2 Tabs auf einer Seite verwendet und möchte nun 3 Tabs auf einer anderen Seite verwenden, aber das Problem, auf das ich stoße, ist die in CSS definierte Breite.
Auf der ersten Seite (2 Tabs) habe ich eine Breite von 380px verwendet
Auf der 2. Seite (3 Tabs) möchte ich eine Breite von 295px verwenden.
Ich möchte das erste Beispiel verwenden, bin mir aber nicht sicher, wie ich es anwenden soll.
Kann mir bitte jemand dabei helfen?
Vielen Dank im Voraus.