想要动态的操作Table就必须熟悉DOM,要想实现浏览器兼容就必须熟悉W3C标准及各个浏览器在表格操作方面的特性。Table是现今数据展示的不二选择,DOM专门为Table添加了一些特性和方法,这有助于我们编写出更简单、高效的程序。
注: 本文的程序在IE7和FireFox3下测试通过。
程序一:动态创建表格
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
1
/*
*
2
* 创建一个特定行、列的表格
3
* @param {Object} rowCount 表格的行
4
* @param {Object} cellCount 表格的列
5
*/
6
function
createTable(rowCount,cellCount){
7
if
(isNaN(rowCount)
||
isNaN(cellCount)){
8
alert(
"
您输入的不是数字
"
);
9
return
;
10
}
else
if
(parseInt(rowCount)
<=
0
||
parseInt(cellCount)
<=
0
){
11
alert(
"
请输入一个大于0的数
"
);
12
return
;
13
}
14
var
tableNode
=
document.createElement(
"
table
"
);
15
16
tableNode.setAttribute(
"
id
"
,
"
tableNode
"
);
17
tableNode.setAttribute(
"
class
"
,
"
tableStyle
"
);
18
tableNode.setAttribute(
"
border
"
,
1
);
19
20
for
(
var
i
=
0
; i
<
rowCount; i
++
){
21
var
newRow
=
tableNode.insertRow(
0
);
22
for
(
var
j
=
0
; j
<
cellCount; j
++
){
23
var
newCell
=
newRow.insertCell(
0
);
24
newCell.innerHTML
=
Number(i
+
1
)
+
"
×
"
+
Number(j
+
1
);
25
}
26
}
27
document.body.appendChild(tableNode);
28
}
这个函数很简单:14行利用document.createElement()方法创建了一个Table标签,到这步我们还没有遇见需要注意的地方,因为大部分浏览器都支持该方法。16-18行我们用setAttribute()方法为新建的table标签加入属性,这几行代码虽然可以被IE和FF解析,但是《JavaScript高级程序设计》一书却指出:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
IE在setAttribute()方法上有很大的问题,当你使用他时,变更并不会总是正确的反应出来,如果你打算支持IE,最好尽可能使用属性。
大师说的话总是有道理的,所以我们可以使用属性代替方法,幸好FireFox也对属性提供了支持,所以我们可以把程序修改如下:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
1
tableNode.id
=
"
tableNode
"
;
2
tableNode.className
=
"
tableStyle
"
;
3
tableNode.border
=
"
1
"
;
唯一要注意的就是,在设置table的class时,要用className。
21行使用的insertRow(),23行使用的insertCell()都是DOM为Table提供的专用API,相应的方法还有deleteRow()和deleteCell(),当使用这两个方法时,我们应该高度注意:IE为两个方法都提供了默认的参数-1,而FireFox却没有为他们提供参数,所以如果没有参数的话,在IE下可以正常运行,但在FireFox下却不行。所以我们应该注意总是为这两个方法提供参数。通俗点可以这样解释这两个函数的参数意思:
0:把新建的行放在已存在行的上面-------总是设置最新的行索引(rowIndex)为0
-1:把新建的行放在已存在行的下面-------行索引递增,从0开始
也可以手动设置该参数,但当设置的参数大于当前table的行索引+1时,程序会报错。insertCell()意思相近,不在重复!
程序二:在指定行的前后插入新建行
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
1
/*
*
2
* 在指定的行索引前或后加入新行
3
* @param {Object} position 标识插入的位置的前后
4
* @param {Object} indexOfRow 行索引
5
*/
6
function
insertNewRow(position,indexOfRow) {
7
var
tableNode
=
document.getElementById(
"
tableNode
"
);
8
if
(tableNode
==
null
){
9
alert(
"
找不到要操作的表格
"
);
10
return
;
11
}
12
if
(
!
isNaN(indexOfRow)
&&
parseInt(indexOfRow)
>
0
){
13
//
通过行索引找到指定的行
14
if
(Number(indexOfRow
-
1
)
<=
tableNode.rows.length){
15
var
tableRow
=
tableNode.rows[indexOfRow
-
1
];
16
}
else
{
17
var
tableRow
=
tableNode.rows[tableNode.rows.length
-
1
];
18
}
19
//
通过cloneNode复制行,得到新行
20
var
newRow
=
tableRow.cloneNode(
true
);
21
//
在指定的行之前插入新行
22
if
(position
==
1
){
23
tableRow.parentNode.insertBefore(newRow,tableRow);
24
}
else
{
25
//
在指定行之后插入新行
26
tableRow.parentNode.insertBefore(newRow,tableRow.nextSibling);
27
}
28
}
else
{
29
alert(
"
请输入一个大于0的数字
"
);
30
return
;
31
}
32
}
程序15行使用的rows的意思是返回包含表格中所有行的一个数组,相应的还有cells:包含表格中所有单元格的一个数组。既然是包含所有行的数组,我们自然可以利用数组索引得到我们所要的值,
20行使用的cloneNode()方法是我最喜欢的DOM方法之一,他可以让我们针对某个特定的HTML元素进行深(参数为true)、浅(参数为false)拷贝,所谓深拷贝的意思是,返回一个当前元素的副本,该副本具有和原有元素相同的特称。当我们需要新建一个和某个已存在元素相同的元素时,(例如多文件上传)这个方法可以帮我们省去很多代码。所谓浅拷贝就是只拷贝元素骨架而不拷贝元素特称,意思不好表达,可以把上面程序cloneNode()方法的参数设置为false以便观察其效果。
23行使用的insertBefore()方法的使用也很简单:在当前元素的前面插入指定的元素,经常看见网上有人说为什么W3C不弄个insertAfter(),其实,我们只需换个方式思考一下,我们在当前元素的下一个元素前面插入指定的元素,那不就实现了insertAfter()方法,嘿嘿!
程序3:删除指定的行
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
1
/*
*
2
* 删除指定的行
3
* @param {Object} deleteRowIndex 要删除行的索引
4
*/
5
function
deleteTheRow(deleteRowIndex){
6
var
tableNode
=
document.getElementById(
"
tableNode
"
);
7
var
rowCount
=
tableNode.rows.length;
8
9
if
(isNaN(deleteRowIndex)
||
parseInt(deleteRowIndex)
<
1
||
parseInt(deleteRowIndex)
>
Number(rowCount)){
10
alert(
"
请输入一个大于0小于
"
+
Number(rowCount)
+
"
数字
"
)
11
return
;
12
}
13
tableNode.deleteRow(Number(deleteRowIndex
-
1
));
14
}
呵呵,这段小程序没什么好说的,用的主要方法是deleteRow(),但要注意:传入的参数不能大于table的行数,否则会报错!
程序4:删除指定的单元格
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
1
/*
*
2
* 删除指定的单元格
3
* @param {Object} indexOfRow 行
4
* @param {Object} indexOfCell 列
5
*/
6
function
deleteTheCell(indexOfRow,indexOfCell){
7
var
tableNode
=
document.getElementById(
"
tableNode
"
);
8
var
rowNode
=
tableNode.rows[Number(indexOfRow
-
1
)];
9
rowNode.deleteCell(Number(indexOfCell
-
1
));
10
}
使用提供的行索引以及列索引找到要删除的单元格,然后调用deleteCell()方法,接下来删除指定列的代码,跟这个类似,无非就是循环table的每一行,找到指定的列,然后删除。