重新排序html表格行

问题描述:

我试图将display:none属性行推到表格的底部。但是,我的代码只推动trdisplay:none属性。第二排停留在同一个位置,我无法将它推到桌子底部。重新排序html表格行

<html> 
<head> 
<script> 
    function moveHiddenRows() 
    { 
    var table = document.getElementById('res'); 
    var rows = table.getElementsByTagName('tr'); 
    for (var a=0, b=rows.length; a<b; a++) 
    { 
     if (rows[a].style.display == 'none') 
     { 
     var row = rows[a].parentNode.removeChild(rows[a]); 
     table.appendChild(row); 
     } 
    } 

    for(var i=0;i<rows.length;i++) 
    { 
     if(i%2==0) 
     rows[i].className="even"; 
     else 
     rows[i].className="odd"; 
    } 
    } 
</script> 
<style> 
    .odd{ 
    background-color:red; 
    } 
    .even{ 
    background-color:yellow; 
    } 
</style> 
</head> 
<body onload="javascript:moveHiddenRows();"> 
    <table id="res"> 
    <tbody> 
     <tr><td>ABC</td></tr> 
     <tr><td>asd</td></tr> 
     <tr style="display:none;"><td>XYZ</td></tr> 
     <tr style="display:none;"><td>asd</td></tr> 
     <tr><td>asd</td></tr> 
     <tr><td>asd</td></tr> 
    </tbody> 
    </table> 
</body> 
</html> 
+0

请保持代码的代码。 – 2011-04-19 06:11:21

部分是在这里:

var table = document.getElementById('res'); 
var rows = table.getElementsByTagName('tr'); 
for (var a=0, b=rows.length; a<b; a++) 
{ 
    if (rows[a].style.display == 'none') 
    { 
     var row = rows[a].parentNode.removeChild(rows[a]); 
     table.appendChild(row); 
    } 
} 

首先,如果块没有内部的声明变量,JavaScript的只有功能范围,从而更好地宣布他们在函数的顶部,所以范围是显而易见的。我会留下来让你解决。其次,在IE行中必须添加一个元素,其他浏览器用于将它们添加到tbody,如果你不这样做,但最近Firefox还没有这样做,所以将它们添加到tBody中。

最后,你的问题是行是HTMLCollection,所以它是活的。当你移动第一行时,在索引1处,它下面的一行变为第一行。因此,在索引2的下一次迭代中,它得到它下面的行(即原来索引为3但现在为2的那一行)移动到底部)。在最后一次迭代中,您将得到已经移动到底部的行。

简单的解决方案是向后通过收集。哦,你不必拆除和更换的元素,你可以将它:

var a=rows.length; 
while (a--) 
{   if (rows[a].style.display == 'none') 
    { 
     rows[a].parentNode.appendChild(rows[a]); 
    } 
} 

不过请注意,该行已在顺序被交换。对于那个很抱歉!将其保存在顺序的替代方法是集合转换为阵列(简单地循环通过收集和添加的行的阵列)与所述计数器,或者麻烦:

for (var a=0, b=rows.length; a<b; a++) 
{ 
    if (rows[a].style.display == 'none') 
    { 
     rows[a].parentNode.appendChild(rows[a]); 
     a--; // Move a up because removed a row 
     b--; // Shorten b so don't visit row again at the bottom 
    } 
} 

因为行并[a] .parentNode是tbody。请注意,这是移动到TBODY的底部,所以如果你有多个TBODY元素,你需要去的最后一个引用,并添加它们有:

var lastTBody = table.tBodies[table.tBodies.length - 1]; 

您使用索引遍历表,该索引在更改表时需要更新。

例如,当您将第二行移到底部时,第三行将变成第二行。由于指数无论如何都在上涨,下一次循环的迭代将看到新的第三条线,这是第四条线。之前的第三行(现在的第二行)因此被忽略。

您可以通过在将行移动到底部之后调整索引来解决此问题。

一旦你停止跳过线条,你将陷入无限循环。您还需要调整长度以不再移动已移动的线条。

例如:

您的问题
table.appendChild (row); 
a--; 
b--; 
+0

或添加所有删除的行后迭代:) – Sam 2011-04-19 06:38:32

+0

@Sam - 是的,这是一个选项,但它需要2个循环。另一种选择是将行转换为数组(也需要额外的循环或函数调用)。我猜测OP必须选择更可维护的东西。 – RobG 2011-04-19 06:50:05

+0

你是正确的,但虽然前者由莱尔肯定是最短的,但我会选择两个循环,我不是一个改变正在迭代槽的迭代仍在进行中的对象的忠实粉丝 – Sam 2011-04-19 06:57:49