2010-09-15 414 views
6

我有一个流体网格(高度和宽度)。 LI始终是矩形,并将它们自己调整为屏幕大小。在列表元素中填充空格

现在我需要填写名单,所以他们都有相同的高度。 如果所有列都有一个LI元素,这将很容易。 但是有两个大小的列,其中一些可以包含大尺寸的LI。在某些情况下,柱子中间甚至有空的空间,因为有一个很大的李,一个小的,然后又是一个大的。

在一些内容页面上,所有的li都在一个列中。

在每一种情况下,李氏都向左漂浮。我做了一些图片来解释这个问题:

grid problemgrid problem2

首先我想指望孩子的并加以比较。但是,当所有的LI都在一个列中,或者在列中间缺少LI时,它会变得复杂。

这是我曾尝试:

var longest = 0 

$("ul.grid-col").each(function(){ 
    var liCount, $that = $(this); 
    liCount = $that.find("> li").length; 

    if ($that.is(".double")){ 
     if($that.find("li.big").length){ 
      var bigCount = $that.find("li.big").length 
      liCount = (liCount - bigCount) + (bigCount * 4) //because one big has the size of 4 small one 
     } 
    liCount = liCount/2 

    } 

    if (longest < liCount){ 
     longest = liCount 
    } 
}) 

现在我知道李的我需要多少来填补空虚的,它很容易填补起来。但是,我怎么知道李的中间是否有空的空间?你将如何处理单列的特殊情况?

+4

你有没有这样做? http://desandro.com/resources/jquery-masonry/ – 2010-09-20 11:18:27

回答

4

我得到了这个在FF工作。希望我能正确理解你的问题。我试图通过构建一个html外壳来模拟你的情况。我不确定它是否与您的代码相符,但我基于您的图像。

我的方法的要点如下:

单柱UL的是相当容易的。遍历所有的ul,看看最大高度是多少。按照li的高度划分maxHeight,并根据需要添加li来填写。

双宽ul有点棘手。我创建了一个简单的数组来表示构成双宽列的单个空格。然后,我遍历每个li并在适当的位置更新空间索引的状态。如果在需要单个的情况下发生双重现象,那么我添加一个新的li。在双ul的li阵列结束后,我再次检查spaces数组以确保ul末尾没有任何空白。

希望代码比我的解释更清晰一点。 :)

<style type="text/css">*    {margin:0; padding:0; list-style:none; border:none; outline:none;} 

    body   {} 

    ul    {float:left; display:inline; background:#efefef; position:relative;} 
    ul.single  {width:50px;} 
    ul.double  {width:100px;} 
    li    {float:left; display:inline; background:#dddddd; -moz-border-radius:10px;} 
    li.single  {height:50px; width:50px;} 
    li.double  {height:100px; width:100px; background:#999999;} 

    .added   {background:#990000 !important;} 
</style> 

<script type="text/javascript"> 
    $(document).ready(function(){ 
     var maxHeight = 0; 
     var maxWidth = 0; 

     // Update the ul to manually set height and widths. 
     $('ul').each(function(){ 
      var height = $(this).outerHeight(); 
      var width = $(this).outerWidth(); 

      $(this).css({ 
       'height': height, 
       'width': width 
      }); 

      if(height > maxHeight) {maxHeight = height;} 
      if(width > maxWidth){maxWidth = width;} 
     }); 

     var single = 50; 
     var double = 100; 

     // go over the li's and see if any spaces are empty. 
     $('ul').each(function(){ 
      if($(this).hasClass('single')){ 
       var totalSpaces = maxHeight/single; 
       var liCount = $(this).find('li').length; 

       for(var i = liCount; i<totalSpaces; i++){ 
        $(this).append('<li class="single added">&nbsp;</li>'); 
       } 
      } else { 
       // Abstract a two column grid. 
       var totalSpaces = maxHeight/single * 2; 

       // Set up an array representation of the spaces. 
       var spaces = []; 

       // Preset all spaces as empty. 
       for(var i=0; i<totalSpaces; i++){ 
        spaces.push(false); 
       } 

       var currentSpace = 0; 

       // Iterate over the li's and update spaces array. 
       $(this).find('li').each(function(index, ele){ 
        if($(ele).hasClass('single')){ 
         spaces[currentSpace] = true; 
         currentSpace++; 
        } else { 
         // Is this the right column? (is the currentSpace odd?) 
         if(currentSpace % 2 != 0){ 
          // Insert a single li. 
          $(ele).before('<li class="single added">&nbsp;</li>'); 
          spaces[currentSpace] = true; 
          currentSpace++; 
         } 
         for(var i=currentSpace; i<(currentSpace + 4); i++){ 
          spaces[i] = true; 
         } 
         currentSpace+=4; 
        } 
       }); 

       // finally, go back over the spaces array and fill in any missing li's from the end. 
       var me = $(this); 
       $(spaces).each(function(index, ele){ 
        if(!ele){ 
         // insert a single li at the end. 
         $(me).append('<li class="single added">&nbsp;</li>'); 
         spaces[index] = true; 
        } 
       }); 
      } 
     }); 
    }); 
</script> 

<ul class="single"> 
    <li class="single">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
</ul> 

<ul class="single"> 
    <li class="single">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
</ul> 

<ul class="double"> 
    <li class="double">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
    <li class="double">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
</ul> 

<ul class="single"> 
    <li class="single">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
</ul> 

<ul class="single"> 
    <li class="single">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
</ul> 

<ul class="double"> 
    <li class="single">&nbsp;</li> 
    <li class="double">&nbsp;</li> 
    <li class="double">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
</ul> 

<ul class="single"> 
    <li class="single">&nbsp;</li> 
    <li class="single">&nbsp;</li> 
</ul> 

<ul class="double"> 
    <li class="single">&nbsp;</li> 
</ul> 

<ul class="double"> 
    <li class="double">&nbsp;</li> 
</ul> 
+0

是的,它接缝,你理解我的问题的权利。让我测试一下:http://jsfiddle.net/kVUKL/ Wow接缝工作,但最后一行似乎有一个porblem。你能告诉我这是从哪里来的吗? – meo 2010-09-22 13:10:25

+0

jsfiddle版本有两个问题: 1 - 渲染框架不够宽,无法容纳所有的ul。我扩大了一点,一切都很好地排列。 2 - 一旦maxHeight被确定,我忘了更新ul的高度。 (虽然这不影响这个特定示例的渲染效果,但它仍然不是很正确)。在添加完所有填充物之后立即将所有ul的高度设置为maxHeight。 – 2010-09-22 17:03:26

+0

我更新了jsfiddle链接的代码。修正ul上的高度问题修复了ul的定位,最终导致包装(由于被左移)。 – 2010-09-23 02:05:21

2

您是否尝试过使用像960.gs这样的CSS框架?它更容易,代码将更加语义化。另外,使用JavaScript进行布局是一个非常糟糕的主意。 JS代码何时执行?如果将其添加到最后,则页面看起来会变形,直到它加载,并且如果您在开始时加载它,那么由于元素尚未加载,它将不起作用。

0

我很确定你不能。这是漂浮物的问题。技术上说,您正在从文档流程中取出元素。你可以做的唯一的事情是在绘制之前计算出每个尺寸的每个尺寸有多少个li,找出它们将要绘制的位置,然后在可能存在空隙的位置添加空的。

然而,为了这个工作,你将不得不找出一个出现间隙的模式,并且放心,它在所有浏览器中都不会相同!

其中一种方法是将所有li分成四个块,以便如果有四个li可以创建一个新的ul,则将四个附加到它。如果它是一个大的李,保持这样。例如:

 
<ul> 
    <li class="large"> 
    <ul> 
     <li></li> 
     <li></li> 
     <li></li> 
     <li></li> 
    </ul> 
    </li> 
    <li class="large"></li> 
    <li class="large"> 
    <ul> 
     <li></li> 
     <li></li> 
     <li></li> 
     <li></li> 
    </ul> 
    </li> 
</ul> 

如果你明白我的意思!