Dies ist ein Code, um die Kopfzeile eines Inhaltsbereichs beim Scrollen durch diesen Inhalt immer am oberen Bildschirmrand sichtbar zu halten. Dann verschwindet sie, wenn Sie an dem relevanten Abschnitt vorbeigescrollt sind.

Ein paar Dinge, die Sie vorab wissen sollten
- Es gibt viele ähnliche Beispiele, aber dieses ist meins.
- Dies funktioniert (noch) nicht auf Mobilgeräten (zumindest nicht auf mobilen Safari, das ich mir angesehen habe). Denn ich weiß nicht viel über JavaScript auf Mobilgeräten und wie man Scroll-Events und Scroll-Positionen erkennt und so weiter.
HTML
Zu Demozwecken identifizieren wir Bereiche, auf die wir eine permanente Kopfzeile anwenden möchten, anhand des Klassennamens „persist-area“ und die darin enthaltene Kopfzeile, die permanent sein soll, mit „persist-header“. Dies sind völlig unsemantische Klassennamen, aber Sie würden dies in Ihrer eigenen Implementierung beheben, indem Sie einfach Ihren eigenen Markup kennen und entsprechende Selektoren anwenden.
<article class="persist-area">
<h1 class="persist-header">
<!-- stuff and stuff -->
</article>
jQuery JavaScript
Das ist die klare Erklärung dessen, was wir tun werden
- Wir durchlaufen jeden permanenten Bereich und klonen die Kopfzeile. Die geklonte Kopfzeile bleibt unsichtbar, bis wir sie brauchen.
- Jedes Mal, wenn das Fenster gescrollt wird, führen wir einige Tests durch.
- Wenn wir in einen Bereich gescrollt sind, der eine permanente Kopfzeile haben sollte, die aber versteckt wäre, enthüllen wir unsere geklonte Kopfzeile in fester Position. Alle anderen permanenten Kopfzeilen werden versteckt.
Das ganze Paket
function UpdateTableHeaders() {
$(".persist-area").each(function() {
var el = $(this),
offset = el.offset(),
scrollTop = $(window).scrollTop(),
floatingHeader = $(".floatingHeader", this)
if ((scrollTop > offset.top) && (scrollTop < offset.top + el.height())) {
floatingHeader.css({
"visibility": "visible"
});
} else {
floatingHeader.css({
"visibility": "hidden"
});
};
});
}
// DOM Ready
$(function() {
var clonedHeaderRow;
$(".persist-area").each(function() {
clonedHeaderRow = $(".persist-header", this);
clonedHeaderRow
.before(clonedHeaderRow.clone())
.css("width", clonedHeaderRow.width())
.addClass("floatingHeader");
});
$(window)
.scroll(UpdateTableHeaders)
.trigger("scroll");
});
CSS
Das einzige CSS, das wir direkt mit JavaScript ändern, ist die Sichtbarkeit der permanenten Kopfzeile. Ich finde das ziemlich akzeptabel. Alle anderen Stile sind zu Recht Teil der Klasse. Es ist ziemlich leicht, alles, was wir brauchen, ist
.floatingHeader {
position: fixed;
top: 0;
visibility: hidden;
}
Und so...
Nutzen Sie es, wie Sie wollen.
Ja, Techniken wie diese funktionieren auf Mobilgeräten nicht aufgrund der begrenzten und immer noch schlechten Unterstützung für feste Positionierung. Ganz zu schweigen davon, dass Scroll-Events auf Mobilgeräten aufgrund der Scroll-Algorithmen, die zur Beschleunigung von Touch-Bewegungen verwendet werden, langsam sind.
Das einzige effektive Mittel, um dies in modernen mobilen Browsern zu erreichen, wäre, die Scroll-Position neu zu berechnen und dann absolut auf der Seite zu platzieren. Aber es ist eine weniger als brauchbare Erfahrung.
Toller Beitrag, aber!
-B
Das sollte auf iOS5 funktionieren, sieht so aus.
Das Timing der Events scheint etwas daneben zu sein, aber es funktioniert in iOS5
So wie ich es verstanden habe, unterstützt iOS 5 die feste Positionierung mit einem anderen Vendor-Präfix. Die feste Positionierung ist also standardmäßig immer noch deaktiviert, aber mit dem speziellen Vendor-Präfix können Sie die Standardeinstellung überschreiben.
Entschuldigung, ich hätte meine Recherche machen sollen, BEVOR ich poste. Feste Position wird standardmäßig unterstützt, es ist die neue `overflow`-Eigenschaft für Touch-Scrolling, die ein spezielles Präfix benötigt.
-webkit-overflow-scrolling: touch;
Chris, verwenden Sie das Beispiel von 3 Kopfzeilen, sodass jedes Mal, wenn q eine neue Kopfzeile wie oben erreicht, diese verschwindet!
Wenn ich jetzt nur eine Kopfzeile verwende, solange sie erscheinen soll, wie kann ich das bestimmen?
Funktioniert nicht auf dem iPad...
"Dies funktioniert (noch) nicht auf Mobilgeräten (zumindest nicht auf mobilen Safari, das ich mir angesehen habe)."
Es funktioniert bereits in iOS 5 :)
Es gibt eine Sache, die mir an `position:fixed` nicht gefällt: Sie fixiert auch die linke Position. Wenn die Fensterbreite kleiner ist als die Breite der festen Kopfzeile, verschiebt das Scrollen nach links den gesamten Seiteninhalt außer dem festen Teil.
Aber es ist möglich, die linke Position eines festen Elements bei Scroll- und Fenstergrößenänderungsereignissen zu ändern. Sie müssen für jeden `.persist-area` in der `UpdateTableHeaders`-Funktion etwas hinzufügen wie:
Vielen Dank. Das war sehr hilfreich :)
Wirklich nett und clever gemacht, vielen Dank :)
Korrigieren Sie mich, wenn ich falsch liege, aber die Kopfzeile wird in diesem Fall immer relativ zum Fenster positioniert sein, da sie eine feste Position verwendet, richtig? Wenn Sie also ein Elternelement verwenden und die Kopfzeile auf das Element positionieren möchten, das nur in der Mitte des Bildschirms erscheinen könnte, wäre das nicht möglich?
Schöner Beitrag, Chris.
Ein Tipp ist die Leistung, die mit dem Anhängen von Handlern an das Scroll-Ereignis verbunden ist, insbesondere an solche, die bei jedem Scrollen das DOM abfragen. Es ist viel besser, die DOM-Referenzen zu cachen, anstatt sie jedes Mal nachzuschlagen.
Twitter hatte dieses Problem einmal und John Resig schrieb einen hilfreichen Beitrag mit einigen alternativen JS-Optionen – http://ejohn.org/blog/learning-from-twitter/
Ich habe viel aus diesem Beitrag gelernt.
Einschließlich der Tatsache, dass es sich um „das ganze Paket“ handelt.
Nicht Kätzchen-Kaboodle.
@Chris Coyier, ich hatte auf einer iPad-Mikro-Website für mein Unternehmen etwas jQuery verwendet. Es erkannte die Scroll-Position und änderte die Position einer Menüleiste. Ich habe es auch verwendet, um automatisch zum Anfang bestimmter Abschnitte basierend auf der aktuellen Position zu scrollen. Ich werde Ihnen einen Link dafür besorgen.
Brillant, vielen Dank. Ich wollte schon immer wissen, wie das geht.
Sehr schön! Ich habe das auf iPhone-Apps gesehen und fand es eine großartige Technik. Ich habe nie darüber nachgedacht, wie man das mit HTML, JS usw. erreichen kann. Danke!!
Tolles Beispiel, Chris.
Ich habe dasselbe kürzlich gemacht, schauen Sie mal hier
studio.conduit.com
Sie sollten sich das iScroll-Projekt ansehen (http://cubiq.org/iscroll). Es wurde speziell zur Lösung dieses Problems für iOS-Geräte entwickelt, funktioniert aber natürlich auch auf anderen modernen mobilen Plattformen.
Der Hauptvorteil von iScroll ist, dass es den Effekt durch intelligente Verwendung von CSS erzielt. Das bedeutet, dass Webbrowser, mobil oder nicht, Hardwarebeschleunigung nutzen. Dies führt zu einem wirklich reibungslosen Effekt.
Sie sollten sich das iScroll-Projekt ansehen (http://cubiq.org/iscroll-4). Es wurde speziell zur Lösung dieses Problems für iOS-Geräte entwickelt, funktioniert aber natürlich auch auf anderen modernen mobilen Plattformen.
Der Hauptvorteil von iScroll ist, dass es den Effekt durch intelligente Verwendung von CSS erzielt. Das bedeutet, dass Webbrowser, mobil oder nicht, Hardwarebeschleunigung nutzen. Dies führt zu einem wirklich reibungslosen Effekt.
Sie haben wirklich sehr coole Sachen zu geben
Das ist eine schöne Benutzerfreundlichkeitsfunktion für tabellenbasierte Inhalte. Hoffentlich werden in Zukunft mehr Websites solche Tricks mögen. Etwas zur Verbesserung der Benutzerfreundlichkeit bei Tabelleninhalten könnte auch sein, jede zweite Zeile mit dem `:nth-child`-Selektor unterschiedlich einzufärben =)
Sie sind in Ordnung für Tabellenkopfzeilen, sollten aber **niemals** für Textüberschriften oder für die Website-Kopfzeile verwendet werden, da sie Inhalte überlappen und unleserlich machen. Sie müssen nach oben scrollen, um sie zu lesen. Feste Elemente ziehen zu viel Aufmerksamkeit vom Inhalt ab (ich hasse diese festen Facebook-Buttons am Rand mancher Websites, die der Scrollleiste folgen).
Es gibt einfach nicht genug Informationen hier, um zu entscheiden, ob Sie eine solche Technik in einem tatsächlichen Design verwenden sollten oder nicht. Wie bei jedem jemals geschriebenen Tutorial hängt die tatsächliche Verwendung von den tatsächlichen Szenarien ab.
Warum lösen Sie am Ende ein Scroll-Ereignis aus? Würde dieses nicht sowieso ausgelöst, da Sie `preventDefault` nicht verwenden?
Ich finde, dass die Kopfzeile etwa 20 Pixel vor dem unteren Rand stoppen sollte, aber das macht die Sache etwas komplizierter. Es macht einfach keinen Sinn, dass die Kopfzeile ganz am unteren Rand des Kastens steht, sodass kein Inhalt sichtbar ist. Das ist nur meine Meinung, ich bin sicher, es gibt Fälle, in denen ich möchte, dass es genau so funktioniert.
Chris, Sie setzen `clonedRow` als Variable, verwenden aber `clonedHeaderRow`.
Schöner Beitrag! =)
Danke für den Beitrag! Ich habe darüber nachgedacht, das für eine Weile zu lernen, aber ich hatte keine Zeit, es zu untersuchen. Glücklich, dass es direkt in meine Inbox geliefert wurde. Ganz zu schweigen davon, dass ich ein langjähriger Fan dieser Website und der darin enthaltenen Tutorials bin. Nochmals vielen Dank!
Das funktioniert perfekt auf meinem Asus Transformer.
Danke! Ich habe mich gerade gefragt, wie das geht. :)
VERDAMMT! Ich liebe dieses neue Design... musste ich einfach sagen.
Ich mag das neue Design auch, besonders das "schwebende Design"!
Großartiges Tutorial! Ich habe mich immer gefragt, wie das gemacht wird. Hoffentlich funktioniert es plattformübergreifend! Danke, Chris.
Schönes Skript, aber ich bekomme es für Tabellen mit dynamischer Breite nicht gut zum Laufen.
Die `td`s in der geklonten Kopfzeile `tr` erben nicht die Spaltenbreite der `tbody td`s.
Schnell & dreckig; um zu illustrieren, was ich zu beschreiben versuche
Versuchen Sie das, sehen Sie, ob es funktioniert
var $floatingHeader = persist_header.clone();
$floatingHeader.children().width(function (i, val) {
return persist_header.children().eq(i).width();
});
$floatingHeader.css(“width”, persist_header.width()).addClass(“floatingHeader”);
persist_header.before($floatingHeader);
Danke, Teapot.
Hat mit geringfügigen Korrekturen wie ein Zauber funktioniert.
Entschuldigung, aber ich konnte Ihren Code nicht richtig zum Laufen bringen. Er würde die Anzahl der `persist-header` auf der Seite für jeden `persist-area` generieren. Ich habe es in ein `.each()` gesetzt und dieses Problem behoben, aber dann hatte es nur die richtige Breite für die erste Tabelle auf meiner Seite (alle Tabellen hatten dynamische Breiten). Ich habe es überarbeitet zu Folgendem.
var floatingHeader; $(".persist-area").each(function(){ floatingHeader = $(".persist-header", this); floatingHeader.before(floatingHeader.clone()); floatingHeader.children().css("width", function(i, val){ return $(floatingHeader).children().eq(i).css("width", val); }); floatingHeader.addClass("floatingHeader"); });Großartig! Ich war beeindruckt, wie ein paar Zeilen JavaScript etwas so Nützliches und Benötigtes tun können.
Mehr als dieser Artikel, ich mag Ihr neues Thema! Jeder einzelne Pixel ist so sexy!
Hallo Herr Coyier,
Würden Sie mir erlauben zu fragen, was Sie verwenden, um Code in Ihren Blogbeiträgen anzuzeigen? Ich habe auf dieser und anderen Websites nach einem Blogartikel gesucht und einige nette Dinge gefunden, aber nichts sah so gut aus wie das, was Sie verwenden. Danke!
Das ist großartig, Mann. Sehr nützlich.
Gmail Inbox hat das. Danke Chris für so tolle Tipps.
Ich habe einige Android-Tests durchgeführt. Auf dem Standard-WebKit-Browser tut sich nichts. Firefox meldet das Ereignis, nachdem ich meinen Finger losgelassen habe. Opera Mobile scheint das Ereignis zu melden, aber die Kopfzeile wird an der falschen Stelle gezeichnet. Es hat die gleiche Verzögerung wie FF.
Ich habe mich nicht die Mühe gemacht, auf Opera Mini zu testen.
Es gibt einen Fehler im Skript.
**persistent-area** und **persist-area** werden in HTML und JavaScript vermischt.
Verdammt, du Autokorrektur!
Fantastisch, Chris. Vielen Dank. Genau das, was ich für ein aktuelles Projekt brauchte.
Für meine Bedürfnisse wollte ich, dass das Element erst nach einigem Scrollen nach unten erscheint. Also habe ich dem Element selbst `display: none` hinzugefügt und dann `.floatingHeader` `display: block` hinzugefügt.
So wie das
.elementClass {
display: none; /*versteckt Element, bis es benötigt wird*/
}
.floatingHeader {
position: fixed;
top: 0;
visibility: hidden;
display: block; /*zeigt Element an, wenn es benötigt wird*/
}
Beispiel
http://www.beamingbioneersvermont.com/presenters.php
[Nach unten scrollen, um es in Aktion zu sehen]
Nochmals vielen Dank!
Danke für dieses tolle Stück Code. Ich implementiere es auf einer Produktseite mit einer großen Tabelle.
Ich frage mich, wie ich den Code ändern soll, damit die Kopfzeile verschwindet, wenn der untere Rand der Kopfzeile das Ende der Tabelle berührt. Jetzt verschwindet sie, wenn der obere Rand der Kopfzeile das Ende der Tabelle berührt. Dies führt dazu, dass eine Kopfzeile unter der Tabelle erscheint.
oder noch besser... lassen Sie die Kopfzeile (`thead`) verschwinden, wenn der untere Rand der Kopfzeile den oberen Rand der Fußzeile (`tfoot`) berührt.
Dieser Code ist zu großartig!
Tatsächlich habe ich ihn angepasst, um mit dem jQuery tablesorter Plugin zu funktionieren, indem ich ihn in ein Widget umgewandelt habe. Schauen Sie sich eine Demo hier an.
Und falls es jemanden interessiert, habe ich tablesorter auf meinem Github geforkt und eine Reihe von Verbesserungen vorgenommen.
Und ja, das Widget kann auch auf die Originalversion von tablesorter angewendet werden :)
Danke Chris!
Gibt es eine Möglichkeit, es mit jquery-2.0.2.min.js zum Laufen zu bringen?
Hallo! Danke für Ihr Tutorial. Es ist fantastisch!
Jetzt versuche ich, diesen Code in WordPress zu implementieren, aber ich schaffe es nicht.
Ich weiß nicht warum, aber es funktioniert nicht. Kann mir jemand bitte helfen?
Ich denke, das Problem liegt in der Zeile
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"Denn ohne diese Zeile funktioniert es nicht und mein WordPress kann diese Zeile nicht lesen.
Vielen Dank im Voraus
Das scheint eine schlechte Idee zu sein, die Kopfzeile zu duplizieren. Was ist, wenn Sie Ereignis-Listener an eine bestimmte ID angehängt haben? Wenn Sie den Code duplizieren, bricht dies die Funktionalität, da zwei Blöcke mit denselben IDs generiert werden, was alles in der Kopfzeile bricht oder Ereignis-Listener dupliziert. Ich habe gerade versucht zu implementieren und bin auf dieses Problem gestoßen. Ich habe begonnen, zu Klassen zu wechseln, aber es ist meiner Meinung nach immer noch eine sehr "hacky" Lösung für das, was Sie erreichen wollen.
Hey Mann, danke für den Code ":)
Aber was ist, wenn ich auch eine Spalte fixieren möchte? Zum Beispiel, wenn ich die Kopfzeile und die erste Spalte einer Tabelle fixieren möchte, aber nur, wenn ich sie betrachte... Dann, wenn ich nach unten scrolle, verschwinden sie, genau wie Sie es getan haben...
Wie könnte ich das machen?
Danke!
Vielen Dank für diese schöne und einfache Lösung! Funktioniert perfekt für meinen Anwendungsfall!
Hallo Chris, ich habe versucht, etwas Ähnliches zu implementieren. Aber ich wollte, dass die Position der `persistant-header` unterhalb der Hauptkopfzeile der Webseite liegt. Ich habe versucht, den schwebenden Header zu ändern als
.floatingHeader{
position: fixed;
top: 60px;
visibility: hidden;
}
wobei 60px die Höhe der Hauptkopfzeile ist.
Die Zeitsteuerung der permanenten Kopfzeile scheint nicht perfekt zu funktionieren. Muss ich noch weitere Änderungen vornehmen?