2011-10-17 63 views
4

使用jQuery分割列表分成相等大小的子列表,什麼是最有效的方式來分割列表最有效的方法使用jQuery

<ul class="columnar"><li></li>... <li></li></ul> 

成幾個子列表

<ul class="column1"><li></li>... <li></li></ul> 
<ul class="column2"><li></li>... <li></li></ul> 

其中除了各子列表(可能是最後一個)有n個項目。

我想盡量減少查詢和操作DOM,並將原始DOM元素移動到新列表中,而不是克隆它們。

+2

移動它們會導致很多DOM操作。最好抓住所有的HTML,在內存中操縱它,然後重新插入它。 –

+0

但我需要保留原始元素,因爲我正在爲.NET應用程序創建表單模板,並且基於以前的經驗,我必須小心,不要刪除可能附加到現有DOM節點的任何事件偵聽器。 – wheresrhys

+1

@Diodeus:你可以將它們全部移動到一個片段中,操作並將片段放回到DOM中,減少迴流次數並加快速度。 –

回答

0

這是我想出迄今:

var $ul = $(this), 
    items = $ul.children("li"), 
    itemCount = items.length, 
    colHeight = Math.ceil(itemCount/3); 

// create temp DOM node to place the new lists in 
var temp = $("<div></div>"), 
    newUL, 
    i = 1; 

while($ul.children("li").length > colHeight) { 
    newUL = $("<ul class=\"columns\"></ul>"); 
    newUL.append(items.filter(":gt(" + ((i * colHeight)-1) + ")").filter(":lt(" + colHeight + ")")); 
    i++; 
    temp.append(newUL.addClass("column" + i)); 
} 
temp.children().insertAfter($ul.attr("class","columns column1")); 
+0

原來,我的原始方法是最快的方法http://jsperf.com/most-efficient-way-to-split-a-list-into-equal-sized-sub – wheresrhys

0

這似乎很好地工作,不知道它是怎麼雖然高效:

<ul id="column"> 
<li>1</li> 
<li>2</li> 
<li>3</li> 
<li>4</li> 
<li>5</li> 
</ul> 

<div id="columns"></div> 

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.2.min.js"></script> 
<script> 
    $(document).ready(function() { 
     var total = $("#column li").size(); 
     console.log(total); 
     var count = 2; 
     var column = 0; 
     for (var i = 0; i < total; i += count) { 
      column++; 
      $("#columns").append('<ul id="column' + column + '"></ul>'); 
      $("#column" + column).html($("#column li").splice(0, count)); 
     } 
     $("#column").remove(); 
    }); 
</script> 
+0

這樣做的麻煩是那片()克隆李的而不是使用原來的。 – wheresrhys

+0

也許拼接(http://www.w3schools.com/jsref/jsref_splice.asp)會比它會從數組中移除元素並返回它們更好? – endyourif

+0

但jQuery集合不是一個真正的數組,切片是少數幾個數組方法之一,將在類似數組的集合上工作;拼接不能應用於jQuery集合據我所知 – wheresrhys

0

另一種可能性是採取看看現有的插件 - multi column lists。插件的作者顯示了代碼 - 你可以看看那裏使用的技術(CSS的組合和分割成更小的列表)。

+0

它看起來像插件需要兩個階段的過程 - 通過每個項目添加一個類,以指定其在 其中的哪一列 - 運行一個jQuery的選擇這些類,並將其選中到相關的列 我懷疑是更多高效,雖然插件看起來已經想到了一切,並provbbaly更好的通用解決方案 – wheresrhys

0

這裏是我的:) endyourif上面的迴應更加簡潔,但是它可能會稍微高效一些,因爲它先組裝所有的片段,然後用一次替換將它們扔到DOM中。

var desiredNoOfCols = 3; 
var $parent = $("<div/>") 
for(var i=1;i<=desiredNoOfCols ; i++){ 
    $parent.append("<ul class='column" + i + "'> </ul>") 
} 

$("#column") 
    .children() 
     .each(function(index, elem){ 
      $parent 
      .children(".column" + ((index+1) % desiredNoOfCols + 1)) 
       .append($(elem).detach()) 
     }) 
    .end() 
    .replaceWith($parent.children()) 
+0

看起來不錯。我想我很快就會設置一個測試頁面來找到一個贏家 – wheresrhys

+0

這不起作用,因爲它將第一列中的第一項,第二列中的第二項等... – wheresrhys