当有空间时加载更多侧边栏内容

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200美元免费信用额度!

一个经典的布局难题是如何在侧边栏中放置多少内容。理想情况下,主要内容区域和侧边栏的高度大致相同,以避免任何一个区域出现较大的空白区域,因为这看起来很奇怪,而且浪费了宝贵的网页空间。如果侧边栏内容较少,并且内容页面较短,那么可能刚刚好,但长内容页面会有很多未使用的侧边栏空间。如果侧边栏内容过多,那么长内容页面看起来不错,但短内容页面会被尴尬地向下推得较远。

一种解决方案是选择某种折衷方案,然后照此执行。另一种方法是采用技术手段,动态加载适合可用空间的适当数量的侧边栏内容。让我们看看如何做到这一点。

经典问题。
可能的解决方案。

测试高度

我们实际上需要在这里测量内容的高度,所以这是 JavaScript 的领域。我将使用 jQuery。所以假设我们有

<section id="main-content">
</section>

<aside>
</aside>

首先,我们将“缓存”这些元素,以便我们不需要多次选择它们。

var 
   mainContent = $("#main-content"), 
   aside       = $("aside");

我们将需要重复测试 aside(侧边栏)的高度,因此我们不需要缓存该高度,但让我们为主要内容区域的高度创建一个变量,该高度不会改变。

var height = mainContent.outerHeight();

现在,我们将运行一个小测试,看看侧边栏是否有空间容纳更多内容(换句话说,其高度值是否低于主要内容区域)

if (height > aside.outerHeight()) {
  // load in more sidebar content
}

加载模块

使用像 jQuery 这样的 JavaScript 库可以轻松地进行 Ajax 内容加载。如果您有一个名为 sidebarmodule.php 的文件,其中包含附加侧边栏材料的标记,您可以像这样加载它

$.get("sidebarmodule.php", function(data) {
	
  // Create sidebar box
  $("<div />", {	
    "class"  : "sidebar-box",
    "html"   : data
		
  // Fade in new module
  }).hide().appendTo(aside).fadeIn();
		
});

但这只处理单个模块。我喜欢准备好一堆模块以根据需要插入,并将它们包含在一个文件中以简化的想法。因此,让我们使 sidebarmodule.php 更智能,并能够根据 GET 参数返回正确的模块。

<?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>";
  }
?>

现在,当我们发出 Ajax 请求以指定我们想要返回哪个模块时,我们将传递该整数参数。注意我们只创建了三个模块?让我们确保如果我们收到没有更多模块的响应,我们不会执行任何操作

var module = 1;

$.get("sidebarmodule.php", { "module": module }, function(data) {
  
  if (data != "No more modules") {
    
    module++;

    // appending and whatnot

  }

});

需要进行一些清理

当我们运行测试并验证是否有空间容纳更多模块时,我们将需要递归地发出此 Ajax 请求以获取更多模块。因此,我们将要做的是将其抽象到一个函数中,然后在需要时再次调用该函数。我们还需要确保如果我们用完了模块,递归就会停止,因此我们将设置一个 done 变量,如果我们从脚本中收到“没有更多模块”的响应,则该变量是一个停止器。

最后,我们将为高度设置一个缓冲变量。如果侧边栏仅比主要内容短 3 像素,我们实际上不需要另一个完整的模块,因此我们将此缓冲区设置为 80 像素,除非侧边栏至少短于此值,否则不会加载另一个模块。

这是整个过程

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();
}

使用说明

我还没有在这个网站上使用这个想法,但我正在考虑它,因为它是一个非常好的例子,说明哪些网站可以从中受益。其中一个考虑因素是需要 JavaScript 的内容,例如此网站上的投票。它仍然肯定可以使用,只是需要确保 JavaScript 事件绑定到传入的元素,因此需要更多一些的调整和思考。

SEO 专家也可能希望在这里发表意见。我不知道这样做的影响。Google(或其他搜索引擎)是否会看到这些动态添加的内容?我认为不会,但侧边栏内容可能并不重要,实际上 Google 不看到它可能更好(页面上与页面实际主题相关的较高百分比的内容)。

演示和下载

请注意,这里有一些 PHP 在起作用,因此不要期望将它下载到您的桌面上并使其工作,它必须位于 PHP 实际可以运行的位置。

查看演示   下载文件