<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>合并表格</title>
<script>
///////////////////////////////////////////////
// 功能:合并表格
// 参数:tb--需要合并的表格ID
// 参数:colLength--需要对前几列进行合并,比如,
//  想合并前两列,后面的数据列忽略合并,colLength应为2
//  缺省表示对全部列合并
// data: 2005.11.6
///////////////////////////////////////////////
function uniteTable(tb,colLength){
// 检查表格是否规整
if (!checkTable(tb)) return;
var i=0;
var j=0;
var rowCount=tb.rows.length; // 行数
var colCount=tb.rows[0].cells.length; // 列数
var obj1=null;
var obj2=null;
// 为每个单元格命名
for (i=0;i<rowCount;i++){
for (j=0;j<colCount;j++){
tb.rows[i].cells[j].id="tb__" + i.toString() + "_" + j.toString();
}
}
// 逐列检查合并
for (i=0;i<colCount;i++){
if (i==colLength) return;
obj1=document.getElementById("tb__0_"+i.toString())
for (j=1;j<rowCount;j++){
obj2=document.getElementById("tb__"+j.toString()+"_"+i.toString());
if (obj1.innerText == obj2.innerText){
obj1.rowSpan++;
obj2.parentNode.removeChild(obj2);
}else{
obj1=document.getElementById("tb__"+j.toString()+"_"+i.toString());
}
}
}
}/////////////////////////////////////////
// 功能:检查表格是否规整
// 参数:tb--需要检查的表格ID
// data: 2005.11.6
/////////////////////////////////////////
function checkTable(tb){
if (tb.rows.length==0) return false;
if (tb.rows[0].cells.length==0) return false;
for (var i=0;i<tb.rows.length;i++){
if (tb.rows[0].cells.length != tb.rows[i].cells.length) return false;
}
return true;
}
</script>
</head><body>
<table width="400" border="1" id="table1">
  <tr>
    <td>a</td>
    <td>for</td>
    <td>100</td>
    <td>200</td>
  </tr>
  <tr>
    <td>a</td>
    <td>for</td>
    <td>150</td>
    <td>230</td>
  </tr>
  <tr>
    <td>a</td>
    <td>if</td>
    <td>100</td>
    <td>200</td>
  </tr>
  <tr>
    <td>a</td>
    <td>if</td>
    <td>300</td>
    <td>240</td>
  </tr>
  <tr>
    <td>a</td>
    <td>if</td>
    <td>320</td>
    <td>230</td>
  </tr>
</table>
<br>
<input type="button" value="合并表格" onClick="uniteTable(table1,2)">
</body>
</html>

解决方案 »

  1.   

    在firfox里有误. 变成 |a| for | 所有数据
      

  2.   

    不过遇到这样一个问题:
    当表格是这样时,它就不合并了:
    |-----|-----|-----|-----|
    |     | for | 100 | 200 |
    |     |-----|-----|-----|
    |     | for | 150 | 230 |
    |     |-----|-----|-----|
    |  a  | if  | 100 | 200 |
    |     |-----|-----|-----|
    |     | if  | 300 | 240 |
    |     |-----|-----|-----|
    |     | if  | 320 | 230 |
    |-----|-----|-----|-----|
      

  3.   

    在firfox中有误的问题,请你自己检查一下。因为我这里没有环境。
    合并不规则的表格,算法对我来说有点难度。在短时间内,我搞不定。
    我也有个问题,你怎么有这种需求,为什么一定要在客户端脚本解决,在服务器端对数据进行预处理不是更方便吗?
      

  4.   


    呵呵,鲁班门前好弄斧啊,我也来试试——其实是刚好也要用到这个功能,写了出来,又刚好查到这个贴子,发觉上面答案的效率太低,且有Bug,所以将我的也贴上来凑凑热闹//支持不规则表头和表体结构,150行 X 42列 的表格合并2列撬时 半秒 左右。<script language="JavaScript">
    function uniteTable(thistab,colLength){
    var rn=thistab.rows.length;//取得行数
    var rowspann=0;
    for(j=colLength-1;j>=0;j--){//从第0列开始,合并多少列
    for(i=rn-1;i>1;i--){//从倒数第一行开始往上检查
    if(thistab.rows[i].cells[j].innerText==thistab.rows[i-1].cells[j].innerText&&thistab.rows[i].cells[j].colSpan==thistab.rows[i-1].cells[j].colSpan){//与上面一行比较,如果两行相等就合计当前行的合并行数,并删除当前行。
    rowspann+=thistab.rows[i].cells[j].rowSpan;
    thistab.rows[i].deleteCell(j);
    }else{
    thistab.rows[i].cells[j].rowSpan+=rowspann;//如果不等就完成当前相同数据的合并。
    rowspann=0;
    }
    }
    }
    }uniteTable(document.all.table1,2);//执行测试。</script>
      

  5.   

    我没有安装火狐,所以firfox下会不会有错,不得而知。
      

  6.   

    请问"qiqunet(瑞旗·广东)"大哥,你贴上来的代码测试过吗??????????经过测试,你的代码是错误的.
    1."uniteTable(document.all.table1,2);//执行测试。",这里用的是全角分号
    2.我把上面这句修改后,没有达到楼主的效果,不按要求的合并了.
    我贴的代码我是测试过的,至少在Window 2000 Advanced Server + IE 6.0 是运行通过的.你说有bug,在哪里?????
      

  7.   


    呵,我的程序没有Bug中文分号是笔误,因为我测试时不是用这种方式测试的,是临时加上去的合并不正确,是你的测试数据太简单了,我没想到居然还有表格没有表头的,所以没去处理表头情况(省几行程序)
    没想到你偏偏就用没有表头的数据来测试。为了满足你这种没有表头的怪表(恐怕不是人看的表格吧?谁看得明啊?)只需要加一个条件检测就行了,更新后的程序及注解如下:
    <table width="400" border="1" id="table1">
      <tr>
        <td>a</td>
        <td>for</td>
        <td>100</td>
        <td>200</td>
      </tr>
      <tr>
        <td>a</td>
        <td>for</td>
        <td>150</td>
        <td>230</td>
      </tr>
      <tr>
        <td>a</td>
        <td>if</td>
        <td>100</td>
        <td>200</td>
      </tr>
      <tr>
        <td>a</td>
        <td>if</td>
        <td>300</td>
        <td>240</td>
      </tr>
      <tr>
        <td>a</td>
        <td>if</td>
        <td>320</td>
        <td>230</td>
      </tr>
    </table>
    <br>
    <script language="JavaScript">
    function uniteTable(thistab,colLength){
    var rn=thistab.rows.length;//取得行数
    var rowspann=0;
    for(j=colLength-1;j>=0;j--){//从第0列开始,合并多少列
    for(i=rn-1;i>0;i--){//从倒数第一行开始往上检查
    if(thistab.rows[i].cells[j].innerText==thistab.rows[i-1].cells[j].innerText&&thistab.rows[i].cells[j].colSpan==thistab.rows[i-1].cells[j].colSpan){//与上面一行比较,如果两行相等就合计当前行的合并行数,并删除当前行。
    rowspann+=thistab.rows[i].cells[j].rowSpan;
    thistab.rows[i].deleteCell(j);
    }else{
    thistab.rows[i].cells[j].rowSpan+=rowspann;//如果不等就完成当前相同数据的合并。
    rowspann=0;
    }
    }
    //检测无表头的表
    if(i==0&&rowspann>0){
    thistab.rows[i].cells[j].rowSpan+=rowspann;//如果不等就完成当前相同数据的合并。
    rowspann=0;
    } }
    }uniteTable(document.all.table1,2);//执行测试。
    </script>
      

  8.   

    你的代码的bug,楼主已经给你说了一部份,你看楼主的回贴就行了。我就不再重复了
    另外一点就是,那段代码做了不少无用功,太慢了,想想,要用客户端处理这些情况,一般来说都是因为要处理的数据量大,怕给服务器造成过多的负担,才将部分工作转交给客户端,如果客户端的代码也半天反应不过来,意义就不怎么大了。愚人之见,也不见得就正确,我想既然我的程序能用的代码,最起码它于我来说是有效的吧。
    你们不喜欢用,我倒不勉强。
      

  9.   

    哈哈~ 哈哈~
    看来你不喜欢别人说你的程序有bug.
    我倒无所谓了,有bug可以改嘛。
    程序效率没有你的高,这也很正常,你看你都两星,咱才两角。这就是新手和高手的区别。但你贸然的掏出一段代码贴上去,别人发现问题后,就说:“怪表(恐怕不是人看的表格吧?谁看得明啊?)”,想起来我就想笑,哈哈~~~
    不过最终还是来了个patch.
    好了,不说这个。在你的“产品介绍”中,强调的一个功能“支持不规则表头和表体结构”,好像有点争议耶。
    测试地址
    http://64.17.131.234/zhujf/test.htm
      

  10.   


    呵,我也像你一样——不在乎的前面那个问题——你认为的Bug,不是你发现的,编这段代码的开始我就没去考虑第一行数据和第二行数据相同的情况,因为世间上没有几个表格不包含表头的,所以不用去考虑,其实也是因为我的网页中不可能出现这种一二行相同的情况。
    贴上来的时候曾经犹豫了一下,但最终也没去动它,只是改了一下调用方法。至于你后面又发现了些什么问题,我也不想再来个“Patch”——你喜欢笑嘛,尽管笑去吧,让你笑到最后去。
      

  11.   

    |-----|-----|-----|-----|
    |  a  | for | 100 | 200 |
    |-----|-----|-----|-----|
    |  a  | for | 150 | 230 |
    |-----|-----|-----|-----|
    |  a  | if  | 100 | 200 |
    |-----|-----|-----|-----|
    |  b  | if  | 300 | 240 |
    |-----|-----|-----|-----|
    |  b  | if  | 320 | 230 |
    |-----|-----|-----|-----|
    效果为
    |-----|-----|-----|-----|
    |     | for | 100 | 200 |
    |     |-----|-----|-----|
    |     | for | 150 | 230 |
    |     |-----|-----|-----|
    |  a  | if  | 100 | 200 |
    |-----|-----|-----|-----|
    |     | if  | 300 | 240 |
    |  b  |     |-----|-----|
    |     |     | 320 | 230 |
    |-----|-----|-----|-----|
    测试一下你们的程序?