Mehr Seitenleisten-Inhalte laden, wenn Platz ist

Avatar of Chris Coyier
Chris Coyier am

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

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.

Klassisches Problem.
Mögliche Lösung.

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.

Demo ansehen   Dateien herunterladen