2010-09-15 42 views
6

Tôi có lưới lỏng (chiều cao và chiều rộng). Các LIs luôn luôn hình chữ nhật và thích ứng với tự của mình với kích thước màn hình.Điền vào các khoảng trống trong phần tử danh sách

Bây giờ tôi cần phải điền vào các danh sách, vì vậy tất cả đều có cùng chiều cao. Điều này sẽ dễ dàng nếu tất cả các cột có một phần tử LI. Nhưng có các cột có kích thước gấp đôi và một số cột có thể chứa LI lớn. Trong một số trường hợp thậm chí còn có không gian trống ở giữa cột, bởi vì có một Li lớn một nhỏ và chỉ sau khi nó lớn một lần nữa.

Trên một số trang nội dung tất cả các li nằm trong một cột.

Trong mọi trường hợp, các li được lưu hành sang trái. Tôi đã thực hiện một số hình ảnh để giải thích các vấn đề:

grid problemgrid problem2

Đầu tiên tôi muốn đếm con và so sánh chúng. Nhưng nó trở nên phức tạp khi tất cả các LI ở trong một cột đơn hoặc khi thiếu LI ở giữa cột.

Đây là những gì tôi đã cố gắng:

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

Bây giờ tôi biết có bao nhiêu LI của tôi cần phải lấp đầy khoảng trống, nó khá dễ dàng để điền vào chúng. Nhưng làm thế nào để tôi tìm ra nếu có một không gian trống ở giữa của li? Và làm thế nào bạn sẽ xử lý các trường hợp đặc biệt của cột đơn?

+4

Bạn đã đi với điều này chưa? http://desandro.com/resources/jquery-masonry/ –

Trả lời

4

Tôi đã làm việc này trong FF. Hy vọng rằng tôi hiểu bạn câu hỏi một cách chính xác. Tôi đã cố gắng mô phỏng tình huống của bạn bằng cách xây dựng một trình bao html để làm việc. Tôi không chắc nó khớp với mã của bạn, nhưng tôi dựa vào hình ảnh của bạn.

Ý chính của cách tiếp cận của tôi là như sau:

Các cột đơn lẻ là khá dễ dàng. Lặp lại tất cả các ul để xem chiều cao tối đa là bao nhiêu. Chia tỷ lệ tối đa theo chiều cao li và thêm li để điền vào khi cần.

Dấu hai cạnh rộng hơn một chút. Tôi đã tạo một mảng đơn giản để biểu diễn các khoảng trống đơn có thể tạo thành các cột rộng kép. Sau đó, tôi bước qua từng li và cập nhật trạng thái của chỉ mục khoảng trống khi được điền ở vị trí thích hợp. Nếu một đôi xảy ra khi một đơn là cần thiết, sau đó tôi thêm một li mới. Sau khi đến phần cuối của mảng li cho ul kép, tôi kiểm tra mảng không gian một lần nữa để đảm bảo không có bất kỳ ô trống nào ở cuối ul.

Hy vọng mã này rõ ràng hơn một chút so với lời giải thích của tôi. :)

<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

có nó đường nối mà bạn hiểu câu hỏi của tôi đúng. Hãy để tôi kiểm tra nó ra: http://jsfiddle.net/kVUKL/ Wow seams để làm việc, nhưng hàng cuối cùng dường như có một porblem. Bạn có thể cho tôi biết nơi này đến từ đâu không? – meo

+0

Có hai vấn đề trên phiên bản jsfiddle: 1 - khung hiển thị không đủ rộng để chứa tất cả các điểm ul. Tôi mở rộng nó một chút và tất cả mọi thứ xếp hàng độc đáo. 2 - Tôi quên cập nhật chiều cao của ul sau khi xác định maxHeight. (Mặc dù điều này không ảnh hưởng đến việc hiển thị cho ví dụ cụ thể này, nhưng nó vẫn không thực sự chính xác). Ngay lập tức sau khi thêm tất cả các li của bộ nạp, bạn có thể muốn đặt chiều cao cho tất cả các ul thành maxHeight. –

+0

Tôi đã cập nhật mã tại liên kết jsfiddle. Sửa chữa vấn đề độ cao trên các sửa chữa của ul vị trí của ul của kết thúc lên gói (do được thả nổi bên trái). –

2

Bạn đã thử sử dụng khung CSS như 960.gs? Dễ dàng hơn nhiều và mã sẽ có nhiều ngữ nghĩa hơn. Ngoài ra, việc sử dụng javascript cho bố cục là một ý tưởng thực sự tồi. Khi nào mã JS sẽ được thực thi? Nếu nó được thêm vào cuối, thì trang sẽ bị méo cho đến khi nó tải và nếu bạn tải nó ngay từ đầu, thì nó sẽ không hoạt động khi các phần tử chưa được tải.

0

Tôi chắc rằng bạn không thể. Đó là vấn đề với phao nổi. Bạn đang lấy các yếu tố ra khỏi dòng chảy của tài liệu, về mặt kỹ thuật. Điều duy nhất bạn có thể làm là tính ra số lượng li bạn có của mỗi kích thước trước khi chúng được vẽ, tìm ra nơi chúng sẽ được vẽ và sau đó thêm những ô trống có thể có khoảng trống.

Tuy nhiên, để làm việc này bạn sẽ phải làm việc ra một mô hình nơi những khoảng trống xuất hiện, và được yên tâm, nó sẽ không giống nhau trong tất cả các trình duyệt!

Một đường vòng sẽ là nhóm tất cả các li trong khối bốn, để nếu có bốn li bạn có thể tạo một ul mới, sau đó nối thêm bốn vào nó. Nếu nó là một li lớn, giữ là như vậy. Ví dụ:

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

Nếu bạn hiểu ý tôi!

Các vấn đề liên quan