2010-09-15 13 views
6

Tengo una cuadrícula fluida (en altura y ancho). Los LI son siempre rectangulares y se adaptan a sí mismos al tamaño de la pantalla.Rellenar espacios vacíos en un elemento de lista

Ahora necesito completar las listas, para que todas tengan la misma altura. Esto sería fácil si todas las columnas tuvieran un elemento LI. Pero hay columnas de tamaño doble y algunas de ellas pueden contener LI de gran tamaño. En algunos casos, incluso hay espacios vacíos en el medio de la columna, porque hay un gran Li pequeño y justo después uno grande.

En algunas páginas de contenido, todas las li están en una sola columna.

En todos los casos, los li's flotan a la izquierda. He hecho algunas imágenes para explicar el problema:

grid problemgrid problem2

principio quería contar el niño y compararlas. Pero se volvió complicado cuando todos los LI están en una sola columna o cuando falta una LI en el medio de la columna.

Esto es lo que he intentado:

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

Ahora sé cuántos LI de lo que necesito para llenar los espacios vacíos, es bastante fácil de llenarlos. ¿Pero cómo averiguo si hay un espacio vacío en medio de los li's? ¿Y cómo manejarías el caso especial de la columna individual?

+4

¿Ha tenido una oportunidad con esto? http://desandro.com/resources/jquery-masonry/ –

Respuesta

4

Tengo esto para trabajar en FF. Espero haber entendido tu pregunta correctamente. Traté de emular tu situación construyendo un shell html para trabajar. No estoy seguro de que coincida con su código, pero me basé en su imagen.

La esencia de mi método es el siguiente:

Los individuales de UL columnas eran bastante fácil. Iterate sobre todos los ul's para ver cuál es la altura máxima. Divida el maxHeight por la altura y agregue li's para completar según sea necesario.

Los ul de doble ancho eran un poco más complicados. Creé una matriz simple para representar los espacios individuales que conformarían las columnas dobles anchas. Luego, reviso cada li y actualizo el estado del índice de espacios como se llenan cuando corresponde. Si ocurre un doble donde se necesita uno solo, entonces agrego un nuevo li. Después de llegar al final de la matriz li para la doble ul, reviso la matriz de espacios una vez más para asegurarme de que no haya ningún vacío al final de la ul.

Afortunadamente el código es un poco más claro que mi explicación. :)

<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

sí, parece que entendiste bien mi pregunta. Déjame probarlo: http://jsfiddle.net/kVUKL/ Parece que funciona, pero la última fila parece tener un problema. ¿Puedes decirme de dónde viene esto? – meo

+0

Hay dos problemas en la versión de jsfiddle: 1 - el fotograma de renderizado no es lo suficientemente ancho para albergar a todos los ul's. Lo amplié un poco y todo se alineó muy bien. 2 - Olvidé actualizar la altura de los ul's una vez que se determina el maxHeight. (Aunque esto no está afectando a la representación para este ejemplo en particular, todavía no es realmente correcto). Inmediatamente después de agregar todos los li's de relleno, es posible que desee establecer la altura de todos los ul en maxHeight. –

+0

Actualicé el código en el enlace jsfiddle. Al solucionar el problema de la altura en el ul, se arregla el posicionamiento de los ul que terminan envolviendo (debido a que flotaron hacia la izquierda). –

2

¿Ha intentado utilizar un marco CSS como 960.gs? Es mucho más fácil y el código será más semántico. Además, usar javascript para el diseño es una muy mala idea. ¿Cuándo se ejecutará el código JS? Si se agrega al final, la página se ve distorsionada hasta que se carga y si la carga al principio, entonces no funcionará ya que los elementos aún no están cargados.

0

Estoy bastante seguro de que no puedes. Ese es el problema con las carrozas. Está sacando los elementos del flujo del documento, técnicamente. Lo único que podría hacer es calcular cuántos li's tiene de cada tamaño antes de que se dibujen, determine dónde van a dibujarse y luego agregue los vacíos donde haya lagunas.

Sin embargo, para que esto funcione, tendrá que encontrar un patrón donde aparezcan los espacios vacíos, y tenga la seguridad de que no será el mismo en todos los navegadores.

Una forma de redondear sería agrupar todas las li's en bloques de cuatro, de modo que si hubiera cuatro li's, podría crear una nueva ul y luego agregar las cuatro a ella. Si fuera un gran li, keep es como tal. Por ejemplo:

 
<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> 

¡Si entiendes lo que digo!

Cuestiones relacionadas