Ein klassisches Layout-Rätsel ist, wie viel *Zeug* in eine Seitenleiste passt. Idealerweise ist die Höhe des Hauptinhaltsbereichs und der Seitenleiste ungefähr gleich, um zu vermeiden, dass einer der Bereiche einen großen leeren Bereich hat, der seltsam aussehen und eine Verschwendung von gutem Webspace sein kann. Wenig Inhalt in der Seitenleiste und kurze Inhaltsseiten sind vielleicht gerade richtig, aber lange Inhaltsseiten haben viel ungenutzten Platz in der Seitenleiste. Viel Inhalt in der Seitenleiste und diese langen Inhaltsseiten sehen gut aus, aber kurze Inhaltsseiten werden unbeholfen weit nach unten geschoben.
Eine Lösung ist, eine Art glücklichen Mittelweg zu wählen und es dabei zu belassen. Eine andere ist, technisch zu werden und dynamisch die entsprechende Menge an Seitenleisteninhalten zu laden, um in den verfügbaren Platz zu passen. Schauen wir uns an, wie Sie das machen könnten.


Höhen testen
Wir müssen buchstäblich die Höhe des Inhalts hier messen, das ist also JavaScript-Territorium. Ich werde jQuery verwenden. Nehmen wir also an, wir haben
<section id="main-content">
</section>
<aside>
</aside>
Zuerst "cachen" wir diese Elemente, damit wir sie nicht mehr als einmal auswählen müssen.
var
mainContent = $("#main-content"),
aside = $("aside");
Wir müssen die Höhe der aside (Seitenleiste) wiederholt testen, daher müssen wir diese Höhe nicht cachen, aber wir erstellen eine Variable für die Höhe des Hauptinhaltsbereichs, die sich nicht ändern wird.
var height = mainContent.outerHeight();
Jetzt führen wir einen kleinen Test durch und sehen, ob die Seitenleiste noch Platz für mehr Inhalt hat oder nicht (mit anderen Worten, ob sie eine niedrigere Höhenangabe hat als der Hauptinhaltsbereich).
if (height > aside.outerHeight()) {
// load in more sidebar content
}
Module laden
Mit einer JavaScript-Bibliothek wie jQuery ist das Ajax-Laden von Inhalten ziemlich einfach. Wenn Sie eine Datei namens sidebarmodule.php hätten, die das Markup für ein zusätzliches Stück Seitenleistenmaterial enthält, könnten Sie es so laden:
$.get("sidebarmodule.php", function(data) {
// Create sidebar box
$("<div />", {
"class" : "sidebar-box",
"html" : data
// Fade in new module
}).hide().appendTo(aside).fadeIn();
});
Aber das behandelt nur ein einzelnes Modul. Mir gefällt die Idee, eine Reihe von Modulen bereit zu halten, die bei Bedarf eingefügt werden können, und sie zur Vereinfachung in einer Datei zu belassen. Machen wir also sidebarmodule.php intelligenter und fähig, das richtige Modul basierend auf einem GET-Parameter zurückzugeben.
<?php
$module = $_GET['module'];
if ($module > 3) { echo "No more modules"; return; }
echo "<h3>Sidebar Box #$module</h3>";
switch($module) {
case 1: ?>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>
<?php break;
case 2: ?>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>
<?php break;
case 3: ?>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>
<?php break;
default:
// Shouldn't ever get here, but just in case output some kind of error
echo "<p class='error'>No more modules</p>";
}
?>
Nun übergeben wir diesen Integer-Parameter, wenn wir die Ajax-Anfrage stellen, um anzugeben, welchen wir zurückhaben möchten. Beachten Sie auch, dass wir nur drei Module erstellt haben? Stellen wir sicher, dass wir nichts tun, wenn wir eine Antwort erhalten, dass keine weiteren Module mehr übrig sind.
var module = 1;
$.get("sidebarmodule.php", { "module": module }, function(data) {
if (data != "No more modules") {
module++;
// appending and whatnot
}
});
Ein paar Aufräumarbeiten
Wir müssen diese Ajax-Anfrage für weitere Module rekursiv durchführen, wenn wir einen Test durchführen und feststellen, dass mehr Module Platz haben. Wir werden es also in eine Funktion auslagern und diese Funktion bei Bedarf erneut aufrufen. Wir müssen auch sicherstellen, dass die Rekursion stoppt, wenn uns die Module ausgehen. Deshalb richten wir eine done-Variable ein, die als Stopper dient, wenn wir die Antwort "Keine weiteren Module" vom Skript erhalten.
Zuletzt richten wir eine Puffer-Variable für die Höhe ein. Wenn die Seitenleiste nur etwa 3 Pixel kürzer ist als der Hauptinhalt, brauchen wir wirklich kein weiteres ganzes Modul. Wir setzen diesen Puffer also auf etwa 80 Pixel, sodass kein weiteres Modul geladen wird, es sei denn, die Seitenleiste ist mindestens um diesen Betrag kürzer.
Hier ist das ganze Paket.
var mainContent = $("#main-content"), /* "Caching" */
height = mainContent.outerHeight(),
aside = $("aside"),
module = 1, /* Start with the first, increments */
buffer = 80, /* To prevent sidebar from growing way taller than main content if it's only barely shorter */
done = false; /* If no more modules to be had */
function getMoreContent() {
$.get("sidebarmodule.php", { "module": module }, function(data) {
if (data != "No more modules") {
// Increment # so next time it will grab a differnet module
module++;
// Create sidebar box
$("<div />", {
"class" : "sidebar-box",
"id" : "sidebar-box-" + module,
"html" : data,
"css" : {
"position": "relative",
"left": 25
}
// Fancy revealing of new content
}).hide().appendTo(aside).fadeIn(200, function() {
$(this).animate({
"left": 0
});
});
// If after getting new module, sidebar is still too short, start over
if ((height > (aside.outerHeight() + buffer)) && !done) {
getMoreContent();
}
}
});
}
// Initial test
if (height > (aside.outerHeight() + buffer)) {
getMoreContent();
}
Hinweise zur Verwendung
Ich nutze diese Idee noch nicht auf dieser Seite, aber ich werde darüber nachdenken, da es ein gutes Beispiel für eine Seite ist, die davon profitieren könnte. Eine der Überlegungen sind Inhalte, die JavaScript benötigen, zum Beispiel die Umfrage auf dieser Seite. Es ist immer noch möglich, dies zu verwenden, es muss nur sichergestellt werden, dass JavaScript-Ereignisse an die eingehenden Elemente gebunden werden, was etwas mehr Tüftelei und Überlegung erfordert.
SEO-Experten mögen hier vielleicht auch ihren Senf dazugeben. Ich habe keine Ahnung von den Auswirkungen. Sehen Google (oder andere Suchbots) diesen dynamisch hinzugefügten Inhalt? Ich würde denken nicht, aber Seitenleisteninhalte sind dafür wahrscheinlich ohnehin nicht wichtig, und es ist vielleicht sogar gut, dass Google sie nicht sieht (höherer Anteil an Inhalten auf der Seite, der sich auf das eigentliche Thema der Seite bezieht).
Demo & Download
Beachten Sie, dass hier PHP im Spiel ist. Erwarten Sie also nicht, dass dies auf Ihren Desktop herunterladen und funktioniert, es muss irgendwo sein, wo das PHP tatsächlich ausgeführt werden kann.
Danke Chris!
Das ist sehr nett, ich werde Ihnen dafür auf meiner Seite Anerkennung zollen.
Ich schließe mich dem an, ich würde gerne dieses Tutorial sehen…
Wir verwenden dynamische Seitenleistenmodule (und Fußzeilenmodule) auf allen von Wikia gehosteten Wikis. Wir verwenden eine Kombination aus serverseitiger Logik und JS, um die Seitenhöhe zu erkennen und ansprechende Ergebnisse für Seiten mit sehr unterschiedlichen Inhaltsmengen zu erzielen (da sie benutzergeneriert sind).
Google wird nun auch Inhalte indizieren, die normalerweise nur über Ajax sichtbar sind, was wahrscheinlich eine weitere gute Idee für ein Tutorial ist. :)
http://code.google.com/web/ajaxcrawling/docs/getting-started.html
Es serverseitig zu tun ist auch nett. Ich könnte mir vorstellen, Wortzählungen von Artikeln durchzuführen und dann Module entsprechend dieser Zählung auszugeben. Oder vielleicht etwas ausgefeilter zu werden und auch Bilder zu messen.
—
Diese
_escaped_fragment_-Sache im Google-Artikel ist interessant. Das wäre definitiv eine gute Arbeit, das alles einzurichten.Sieht aus wie von Twitter? https://twitter.com/?_escaped_fragment_=/1Password/statuses/17325144028479488
Ja, es serverseitig zu tun, erinnert mich an Jonathan Snooks Artikel von 2007, in dem er das mit CakePHP gemacht hat: http://snook.ca/archives/cakephp/elemental_conditional_content_with_cakephp
Ich denke aber, dass es mit einer JS-Implementierung mehr Spaß macht :)
Chris,
Sie könnten natürlich auch den gesamten Inhalt in versteckte Abschnitte laden und JS verwenden, um sie basierend auf der Höhe anzuzeigen/auszublenden.
Dadurch könnte Google den gesamten Inhalt sehen, egal wie hoch die Seite ist, und Sie müssen sich nicht mit Ajax herumschlagen :)
Das klingt nach dem, was ich gedacht habe, als ich den Titel des Artikels zum ersten Mal las. Was wäre Ihr Vorgehen, um diese Methode zu implementieren, TechWraith?
Hallo Chris,
Sehr schöne Idee. Ich bin schon so oft in diese Situation geraten. Es ist schön, ein nützliches Szenario wie dieses zu sehen.
Ich mag die Idee, frage mich aber, ob nicht der gegenteilige Ansatz besser wäre. Alle Seitenleisteninhalte laden und dann Module basierend auf der Höhe des Hauptinhalts ausblenden. Wenn der Benutzer kein JavaScript aktiviert hat, sieht er alles, und das sollte auch die SEO-Bedenken abdecken. Es wäre auch deutlich einfacher, da Sie keine AJAX-Anfragen stellen müssen.
Ja, das würde ich auch bevorzugen. (Y)
Das Problem dabei ist, dass, wenn etwas auf der Seite länger zum Laden von Inhaltsblöcken benötigt, diese verschwinden, sobald das JavaScript geladen ist. Das könnte den Besucher fragen lassen, wohin es verschwunden ist.
Toller Artikel.
Um ehrlich zu sein, mag ich den ganzen leeren Platz in der Seitenleiste, wenn der Inhalt der Seite sehr lang ist. Er hält mich auf den Inhalt fokussiert, weswegen ich gekommen bin.
Allerdings denke ich, dass Seiten mit Seitenleisteninhalten, die die Hauptinhalte bei weitem übertreffen, davon profitieren würden, gekürzt zu werden. Wie zum Beispiel auf Ihrer https://css-tricks.de/contact/ Seite.
Das ist ein guter Punkt, James.
Das ist auch meine Denkweise. Ich habe kürzlich eine Website von einer Zeitschrift portiert und den Leerraum unter der Navigationsleiste links genutzt, um eine "Zurück nach oben"-Box einzublenden, sobald der Benutzer ein Stück weiter nach unten gescrollt ist als die Seitenleiste; eine viel bessere Nutzung des Raumes in diesem Fall, als mehr Inhalt einzufügen.
Das soll aber nicht unnötig negativ sein, dieser Trick ist ziemlich cool und wäre in manchen Fällen sicherlich angebracht. (Zum Beispiel, um zusätzliche Anzeigen auf einer langen Seite zu präsentieren und kürzere Seiten ohne zusätzliche Unordnung zu lassen.) Aber ich denke, manche Leute neigen dazu, Leerraum zu füllen, der besser offen gelassen würde.
Wäre toll mit unendlichem Scrollen…
Ich mag diese Idee wirklich. Eine vertikal scrollende Seitenleiste. Segmente, die elegant oben verschwinden und die gesamte Seitenleiste nach oben bewegt, während Segmente unten hinzugefügt werden. Wenn keine Segmente mehr vorhanden sind, beginnen Sie wieder mit Segment Nummer eins unten. Vorzugsweise bleibt es im Browserfenster. Wenn die Seitenleiste im Fokus ist (Maus über?), wäre es schön, das Scrollen mit dem Mausrad zu steuern. Macht das Sinn?
Ich wünschte, ich könnte so etwas erstellen. Das wäre ein schöner Screencast (zwinker zwinker).
Grüße an euch alle. Habt frohe Weihnachten und ein glückliches neues Jahr.
Ich wette, das Slider-Ding wäre ein guter Anfang…
Ich glaube… Sie machen gute Arbeit… aber irgendwie sollten Sie Ihren Weg ändern.
Das ist wirklich großartig! Etwas anderes, das funktionieren könnte (in WordPress), ist die Wortzahl zu ermitteln und dann eine if-Anweisung auszuführen, wodurch die Notwendigkeit von JS entfällt. Wenn Sie ein Caching-Plugin verwenden, sollte die Auswirkung minimal sein.
Tolle Idee aber :)
Das Problem, das ich beim Zählen von Wörtern sehe, ist, dass man die Höhe nicht wirklich bestimmen kann. Was Chris bereits erwähnt hat, Bilder und andere Dinge spielen eine wesentliche Rolle für die Höhe. Was bedeutet, dass es nicht sehr genau sein wird.
Chris, das rockt wirklich! Chris rockt!!!!!
Wirklich coole Idee! Und ich nehme an, wenn JS deaktiviert ist, werden einfach keine zusätzlichen Elemente in der Seitenleiste angezeigt, also ist es gut abwärtskompatibel.
Offtopic: Ich wusste nicht, dass man mehrere Variablen in jQuery deklarieren kann, indem man eine kommagetrennte Liste verwendet. Funktioniert das auch in traditionellem JS, oder ist das eine Funktion, die nur jQuery vorbehalten ist?
Ja, das ist eine JavaScript-Sache, die von jsLint empfohlen wird – Option "Allow one var statement per function". Ich finde es sauberer und leichter zu lesen. Ich bin mir nicht sicher, ob es die Leistung verbessert, es wäre interessant zu sehen, ob jemand anderes es weiß?
Ein guter Artikel dazu ist bei Nettuts+ zu finden. Ich hoffe, das hilft.
Schöner Trick!!
Solange noch etwas angenehmer "weißer Raum" bleibt, um alles sauber und schön zu halten, liebe ich die Idee.
Ein anderer ähnlicher Ansatz, den ich kürzlich gesehen habe, ist, die Seitenleiste zu fixieren: Wenn der Benutzer nach unten scrollt, scrollt die Seitenleiste mit. Hier ist ein Beispiel, das mit CSS und JavaScript gemacht wurde: http://xaviesteve.com/agile-scrum-google-spreadsheet-template-for-freelancers/
Seltsam ist, dass Flash-Objekte "blinken", wenn sich die CSS-Eigenschaft ändert, wohl aufgrund der Neumalung/Neuzeichnung des DOM.
Ich denke, es ist besser, diesen Platz in der Seitenleiste leer zu lassen, da dies die Lesbarkeit verbessert – Bewusstsein für die Bedürfnisse Ihres Lesers schafft Vertrauen, es ist besser, den Bildschirm im mittleren Bereich, wo der Benutzer liest, einfach zu halten.
Toller Beitrag, danke! Würde diese Situation auf Mobilgeräten funktionieren? Ich habe auf meinem iPhone festgestellt, dass Text anders gerendert wird und Seitenleisten kürzer erscheinen können, da der Text im Hauptinhaltsbereich größer dargestellt wird. Ich würde annehmen, dass das JavaScript die Höhe auf dem von Ihnen verwendeten Gerät genau erkennt?
Nochmals vielen Dank!
Ich habe kürzlich etwas Ähnliches auf den Blog-Artikelseiten meiner Website implementiert. Da das Laden zufälliger Module für meine Website keinen Sinn ergibt, lade ich Anzeigen. Der Code ist etwas anders, aber die Idee ist dieselbe: den Inhaltsbereich messen und die größten möglichen Anzeigen, bis zu 2 Anzeigen, hinzufügen, um den verbleibenden Platz zu füllen, falls vorhanden.
Sehen Sie es hier in Aktion: http://af-design.com/blog/ und klicken Sie auf einen beliebigen Artikel.
Toller Artikel, danke. Großer Fan von asynchronen Aufrufen an einen Proxy für verschiedene Dinge.
Aber es gibt ein Problem, wenn man eine Seitenleiste auf bestimmten Seiten einfügt. Sie wird den Fokus auf den Seiteninhalt reduzieren. Besucher können von den Links in der Seitenleiste navigieren. Angenommen, wir fügen eine Seitenleiste auf einer Produktseite ein, die Leute könnten von dieser Seite über die Links in der Seitenleiste navigieren und die Produkte werden nicht bemerkt. Diesen Punkt habe ich aus einigen Podcasts und stimme ihnen voll und ganz zu.
Das Caching der jQuery-Objekte ist eine gute Idee, aber in diesem Fall müssen Sie #main-content wirklich nicht cachen. Sie extrahieren seine Höhe nur einmal, also speichern Sie einfach die Höhe, sonst verschlechtern Sie tatsächlich die Leistung des Skripts.
Ich stimme dieser Idee nicht wirklich zu. Meistens zeigt sich dieses "Problem", wenn man versucht, einen langen Artikel zu lesen. Ich mag die Tatsache, dass nach etwas Scrollen praktisch alle Ablenkungen beseitigt sind. In einer Seitenleiste gibt es nichts, was ich mir ansehen möchte, wenn ich einen langen Artikel lese.
Ich denke, so etwas hat einen Nutzen, aber nicht nur, um Platz um des Platzes willen zu füllen.
Hallo Chris
Wie immer, toller Artikel. Das Einzige, was mir aufgefallen ist, ist, dass Sie die $ Code-Konvention "vergessen" haben: Wenn es sich um ein jQ-Objekt handelt, stellen Sie der Variable ein $ voran, ansonsten nicht.
Ist das etwas Neues oder nur dieser Artikel?
Sehr interessanter Blickwinkel, ebenso wie einige gute Ideen in den Kommentaren. Ihre Seite wird mit der Zeit immer cooler. :)
Alles Gute
Wolff
Manche Leute ziehen es vor, jQ-Objekte nicht mit $ zu präfixen, da es ihrer Meinung nach zu sehr nach ungarischer Notation ist.
Ich persönlich folge dieser Konvention nicht mehr.
Ich mag diese Idee auch, mit dem Vorbehalt, dass sie den Hauptinhalt nicht beeinträchtigt. Manchmal, besonders auf Blogs, fühlt es sich an wie ein Minenfeld, sich um die Anzeigen herumzuarbeiten, um einen Beitrag zu lesen.
Liebe die Idee des AJAX-Hits, um "echte" Inhalte anzuzeigen oder etwas, das die Benutzererfahrung verbessert.
Ich arbeite gerade an einem jQuery-Plugin, mit dem Sie Container taggen können, sodass beim Scrollen nach unten wichtige Elemente in der Seitenleiste zu "fixed" werden und nach unten folgen. Ich werde es für verwandte Artikel verwenden.
erstaunlich..... sprachlos :)
Cooler Artikel eigentlich! Was verwenden Sie für die Codehervorhebung?
Fantastische Artikel. Danke für die nützlichen Tipps, Chris.
Das ist genau das, was ich gesucht habe.
Ich werde das in einigen zukünftigen Projekten verwenden und sicherstellen, dass Sie die entsprechende Anerkennung erhalten.
Danke für einen weiteren guten Beitrag.
Sehr nützlich, danke Chris!
Ich möchte kurz auf den SEO-Standpunkt eingehen. Ich weiß, dass einige "Experten" sagen werden, dass diese Lösung falsch ist. Aber, wie Sie am Ende des Beitrags erwähnen – die Seitenleiste ist nichts Wichtiges! Wenn Sie Ihre Website gestalten, sollten Sie sich keine Sorgen machen über "Was ist mit Google?". Glauben Sie mir, wenn Sie eine gute Website, einen Tipp, eine Lösung usw. erstellen, wird der Benutzer sie finden. Immer :).
Hallo,
Ich verstehe nicht, wo die Variable "done" auf true gesetzt wird?
Vielleicht fehlt ein else-Block im "if (data != “No more modules”)"?
Wie auch immer, großartiges Tutorial, sehr nützlich und leicht verständlich!
Es sieht so aus, als ob ich zu einem bestimmten Zeitpunkt versucht habe, eine "done"-Variable zu verwenden, sie aber am Ende nicht benötigte und diesen Code nicht entfernt habe. Was passiert ist, ist, dass, wenn die Höhe größer wird, es sich einfach nie wieder selbst aufruft, und so stoppt es.