本人试图构造一个可以自由编辑的表格。所谓的自由编辑,就是像在excel编辑表格那么容易,可以新增、删去行或列,可以自由合并单元格。
首先,想先完成第一步:合并单元格。
1.Table基本操作
在实现之前,先要了解js对表格的基本操作,在这里主要需要用到的方法是insertRow和insertCell,很容易理解,就是插入行或单元格。
insertRow(n)表示在第n行(前)插入行,即插入之后它就是第n行。默认为最后一行等同于insertRow(-1),不过很容易理解,它不等于insertRow(length_of_row)哦。
insertCell与上述类似。
对于表格的单元格,是用table.rows[i].cells[j]来获得的,这个得到的就是该单元格的实例,如果要改变它的一些参数,比如接下来要说的单元格“大小”,又比如以后要研究的单元格风格(比如边框、底纹等)都将通过它来操作。于是我写了个函数getCell,就是已知单元格的位置(i行j列)可以返回该单元格实例,省去了table.rows.cell这样的冗余,当然还有个好处,可以做一些验证,比如cell是不是不存在之类的。
2. 合并方法
合并单元格的实现非常容易,因为HTML语言中有自带的单元格属性可以做到合并单元格效果,那就是rowSpan和colSpan,即该单元格横跨行宽度和列宽度。所以关键的参数其实就是两个:要合并的单元格所在的位置、要合并的单元格的总范围。当然,有面向对象经验的你不难发现,其实必须还需要一个参数,“合并哪张表格”,不过接下来几乎所有函数都需要有这个参数,不多讨论。
每个参数都是二维的,位置,即所要合并单元格最左上角的单元格所在位置,比如第i行,第j列。范围,即合并了总共几行,几列。
所以函数很简单就解决了
function merge_cell(table,startPoint,rectangle){
var cell=getCell(table,startPoint);
cell.rowSpan=rectangle[0];
cell.colSpan=rectangle[1];
}
于是我尝试了以C3为位置,合并2行3列的单元格,结果变成这样了
才发现,如果合并了几个单元格,原本所在的位置并不会自动没有,而是自动向后延生,导致整个表格构架就变了。
所以,想要真正实现合并,还得删掉那些多余单元格。这些单元是除原来所在位置的单元格外所有被合并的单元格,显然,第一行和第后面几行是不一样。这里不详细说,不过这里不得不提醒一个细节比如在这里,如果用
for (var j=startPoint[1];j
row.deleteCell(j);}
肯定是会出错的,原因是,第j个单元格被删掉以后,原来j+1的单元格变成了第j,而第j+1个单元格其实是原来第j+2个,所以循环到下一个j时删除的是再后面的单元格。解决方法是
for (var j=startPoint[1];j
row.deleteCell(startPoint[1]);
}
同样的,如果要讲这个单元格拆分,自然光修改rowSpan和colSpan也是不行的,还是得把原来被删掉的单元格增加回来。
而这里增加的时候,就不能再和前面一样,锁定insertCell的参数了,而是随着j变而变的。
具体实现方式,我把代码托管了run.js上面,这是个js代码分享的好网站,不仅可以托管代码,还可以有简单的ide,能够方便地编辑与预览。如果仔细观察不难发现,我里面有个冗余的操作,就是每次insertCell的时候,都需要手动将他们内容设置为对应的内容,可见insertCell势必需要重写,因为新建的cell将来一定还会有更多的需要提前给定的属性,比如onclick事件等。