本文通过具体代码实例,详细讲解如何利用DOM 1.0标准在JavaScript中动态创建和控制HTML表格。内容涵盖使用createElement、appendChild、createTextNode等方法构建表格结构,以及如何通过childNodes和setAttribute获取节点内容与属性。此外,还演示了结合CSS style属性动态修改单元格样式与隐藏列的实用技巧,适用于IE5、Firefox等支持DOM 1.0的浏览器环境。
DOM动态创建表格概述
本文简要介绍DOM 1.0中一些基础且强大的方法,并展示如何在JavaScript中应用这些技术。读者可以学习到如何动态地创建、获取、控制以及删除HTML元素。这些DOM方法同样适用于XML文档。只要浏览器全面支持DOM 1.0,例如IE5、Firefox等,本文提供的实例都能正常运行。
概况 - Sample1.html
本文将通过代码实例深入介绍DOM的使用。请从尝试下面的HTML示例开始,该示例利用DOM 1.0的方法,通过JavaScript动态生成一个HTML表格。代码构建了一个包含四个文本单元格的简单表格,每个单元格显示其所在的行号和列号,格式为“单元格是第y行第x列”。
具体代码如下所示:
<html>
<head>
<title>实例代码 - 使用JavaScript和DOM创建HTML表格</title>
<script>
function start() {
//获取body标签
var mybody = document.getElementsByTagName("body")[0];
// 创建一个<table>元素和一个<tbody>元素
mytable = document.createElement("table");
mytablebody = document.createElement("tbody");
//创建所有的单元格
for(var j = 0; j < 2; j++) {
// 创建一个<tr>元素
mycurrent_row = document.createElement("tr");
for(var i = 0; i < 2; i++) {
// 创建一个<td>元素
mycurrent_cell = document.createElement("td");
//创建一个文本节点
currenttext = document.createTextNode("单元格是第"+j+"行,第"+i+"列");
// 将创建的文本节点添加到<td>里
mycurrent_cell.appendChild(currenttext);
// 将列<td>添加到行<tr>
mycurrent_row.appendChild(mycurrent_cell);
}
// 将行<tr>添加到<tbody>
mytablebody.appendChild(mycurrent_row);
}
// 将<tbody>添加到<table>
mytable.appendChild(mytablebody);
//将<table>添加到<body>
mybody.appendChild(mytable);
// 将表格mytable的border属性设置为2
mytable.setAttribute("border", "2");
}
</script>
</head>
<body onload="start()">
</body>
</html>注意我们创建各元素和文字节点的顺序:
构建表格元素的顺序与步骤
1. 创建<table>元素 2. 创建<table>的子元素<tbody> 3. 使用循环创建<tbody>的子元素<tr> 4. 分别使用循环为每个<tr>创建子元素<td> 5. 为每个<td>创建文本节点
在创建完<table>、<tbody>、<tr>、<td>元素及文本节点后,我们按相反的顺序将它们依次添加到各自的父节点中。 1. 将创建的文本节点添加到<td>中
mycurrent_cell.appendChild(currenttext);
2. 将列<td>添加到行<tr>
mycurrent_row.appendChild(mycurrent_cell);
3. 将行<tr>添加到<tbody>
mytablebody.appendChild(mycurrent_row);
4. 将<tbody>添加到<table>
mytable.appendChild(mytablebody);
5. 将<table>添加到<body>
mybody.appendChild(mytable);
请牢记这一方法,在使用W3C DOM时这将频繁用到。基本思路是:先自上而下构建元素,再自下而上将它们添加到父节点。以下是JavaScript代码生成的HTML结构:
... <table border=5> <tr><td>单元格是第0行,第0列</td><td>单元格是第0行,第1列</td></tr> <tr><td>单元格是第1行,第0列</td><td>单元格是第1行,第1列</td></tr> </table> ...
此乃代码生成的表格元素及其子元素的DOM对象树:
仅需调用少量DOM方法即可构建该表格及其子元素。务必牢记所创建的构造模型树,这将简化编码过程。在图示的<table>结构中,<table>包含一个子元素<tbody>。<tbody>拥有两个子元素。<tbody>的每个子元素(即<tr>)均包含两个< td >子元素。最终,每个<td>包含一个子元素:文本节点。
基础DOM方法 - Sample2.html
getElementByTagName方法既适用于文档也适用于元素,因此文档根对象与所有元素对象均具备 getElementByTagName 方法。你可以利用 element.getElementsByTagName(tagname) 获取指定标签名的所有子元素列表,并通过标签名进行筛选。
element.getElementsByTagName 返回特定标签名字元素的列表。你可通过调用item方法(传入index参数)从子元素列表中获取指定元素。请注意,列表中首个子元素的索引为0。下一主题将延续前述Table示例。以下实例更为简洁,展示了若干基本方法:
获取DOM元素与设置属性
具体代码如下:
<html>
<head>
<title>实例代码 - 使用JavaScript和DOM创建HTML表格</title>
<script>
function start() {
// 获取一个包含所有body元素的列表(将只有一个)
// 然后选择列表里的第一个元素
myBody = document.getElementsByTagName("body")[0];
// 获取body子元素中所有的p元素
myBodyElements = myBody.getElementsByTagName("p");
//获取p元素列表的第二个元素(索引从0开始)
myP = myBodyElements[1];
}
</script>
</head>
<body onload="start()">
<p>hi</p>
<p>hello</p>
</body>
</html>
在此示例中,我们将myP变量设置为表示body中第二个p元素的DOM对象。 1. 获取包含所有body元素的列表
myBody = document.getElementsByTagName("body")[0];
由于有效的HTML文档仅包含一个body元素,该列表只有一项。我们通过使用[0]选取列表的第一项来获取它。 2. 获取body子元素中所有的p元素
myBodyElements = myBody.getElementsByTagName("p");
3. 选取p元素列表的第二项
myP = myBodyElements[1];
一旦获取了HTML元素的DOM对象,即可设置其属性。例如,若要设置style背景色属性,只需添加:
myP.style.background = "rgb(255,0,0)";
文本节点与元素插入删除
使用document.createTextNode("..")创建文本节点 通过调用文档对象的createTextNode方法建立文本节点。只需输入文本内容,返回值即为表示该文本节点的对象。
myTextNode = document.createTextNode("world");
以上代码创建一个文本数据为“world”的TEXT_NODE类型(文字块)节点,变量myTextNode指向该节点对象。需将该文本节点设置为其他节点元素的子节点,才能将其插入HTML页面。 使用appendChild(..)插入元素 因此,通过调用myP.appendChild([node_element]),可将该文本节点设为第二个p元素的子节点。
myP.appendChild(myTextNode);
测试此示例,注意“hello”和“world”两个词是连在一起的:“helloworld”。因此在查看HTML页面时,这两个文本节点hello和world看起来像一个节点,但实际上文档模型中存在两个节点。第二个节点是一个新的TEXT_NODE类型节点,且是第二个p标签的第二个子节点。下图展示了文档树中刚创建的文本节点。

createTextNode和appendChild是在hello和world之间添加空格的一种简单方法。需特别注意,appendChild方法将内容添加在最后一个子节点之后,就像world被添加到hello后面。因此,若想在hello和world之间添加文本节点,应使用insertBefore方法而非appendChild。
使用文档对象和createElement(..)方法创建新元素 可以使用createElement方法创建新的HTML元素或任何其他所需元素。例如,若想为<body>元素添加一个子节点<p>元素,可使用前例中的myBody添加一个新元素节点。创建节点只需调用document.createElement("tagname")。例如:
myNewPTAGnode = document.createElement("p"); myBody.appendChild(myNewPTAGnode);
使用removeChild(..)方法删除节点
每个节点均可被删除。下面这行代码删除了myP(第二个<p>元素)中包含单词world的文本节点。
myP.removeChild(myTextNode);
最后,你可以将包含单词world的文本节点myTextNode添加到新创建的<p>元素中:
myNewPTAGnode.appendChild(myTextNode);
表格结构回顾与属性操作
修正后的对象树最终如下所示:
动态创建一个表格(回到Sample1.html)
文章剩余部分将回到Sample1.html。下图显示了示例中创建的表格的对象树结构。
回顾HTML表格结构
创建元素节点并将它们添加到文档树
创建sample1.html中表格的基本步骤:
获取body对象(文档对象的第一项) 创建所有元素 最后,按照上图的表格结构添加每一个子节点。以下源代码是sample1.html的注释说明
start函数的末尾有一行新代码,使用另一个DOM方法setAttribute设置了表格的border属性。setAttribute方法有两个参数:属性名和属性值。你可以使用setAttribute方法设置任何元素的任何属性。
具体代码如下:
<head>
<title>实例代码 - 使用JavaScript和DOM创建HTML表格</title>
<script>
function start() {
// 获取body
var mybody = document.getElementsByTagName("body")[0];
// 创建<table>和<tbody>元素
mytable = document.createElement("table");
mytablebody = document.createElement("tbody");
//创建所有的单元格
for(var j = 0; j < 2; j++) {
// 创建一个 <tr> 元素
mycurrent_row = document.createElement("tr");
for(var i = 0; i < 2; i++) {
// 创建一个<td> 元素
mycurrent_cell = document.createElement("td");
// 创建一个文本节点
currenttext = document.createTextNode("单元格是第" + j + "行,第" + i + "列");
// 把创建的文本节点添加到<td>元素
mycurrent_cell.appendChild(currenttext);
// 把<td>添加到<tr>行
mycurrent_row.appendChild(mycurrent_cell);
}
// 把<tr>行添加到<tbody>
mytablebody.appendChild(mycurrent_row);
}
// 把 <tbody> 添加到 <table>
mytable.appendChild(mytablebody);
// 把 <table> 添加到 <body>
mybody.appendChild(mytable);
// 把mytable的border属性设置为2;
mytable.setAttribute("border","2");
}
</script>
</head>
<body onload="start()">
</body>
</html>使用DOM和CSS处理表格
从表格中获取一个文本节点
获取节点内容与CSS样式控制
此示例介绍了两个新的DOM属性。首先使用childNodes属性获取mycel的子节点列表。该childNodes列表包含所有子节点,无论其名称和类型如何。与getElementsByTagName方法类似,它返回一个子节点列表,使用[x]获取想要的子节点项。此示例将myceltext存储为表格第二行第二个单元格的文本节点。最后,它创建一个新的包含myceltext的data属性的文本节点,并使其成为<body>元素的子节点,以显示此示例的最终结果。
若对象是文本节点,可使用data属性获取其内容
具体代码如下:
mybody = document.getElementsByTagName("body")[0];
mytable = mybody.getElementsByTagName("table")[0];
mytablebody = mytable.getElementsByTagName("tbody")[0];
myrow = mytablebody.getElementsByTagName("tr")[1];
mycel = myrow.getElementsByTagName("td")[1];
// mycel的子节点列表的第一项
myceltext=mycel.childNodes[0];
// currenttext的内容是myceltext的data
currenttext=document.createTextNode(myceltext.data);
mybody.appendChild(currenttext);获取一个属性值
在sample1的末尾,有一个单元格使用了mytable对象的setAttribute方法。该单元格用于设置表格的border属性。使用getAttribute方法来获取此属性:
mytable.getAttribute("border");
通过改变style属性隐藏列 当使用JavaScript变量指向对象时,可立即设置其style属性。以下代码是sample1.html的修改版,第二列的单元格被隐藏,第一列的单元格背景改为红色。注意style属性是直接设置的。
具体代码如下:
<html>
<body onload="start()">
</body>
<script>
function start() {
var mybody =document.getElementsByTagName("body")[0];
mytable = document.createElement("table");
mytablebody = document.createElement("tbody");
for(var j = 0; j < 2; j++) {
mycurrent_row=document.createElement("tr");
for(var i = 0; i < 2; i++) {
mycurrent_cell = document.createElement("td");
currenttext = document.createTextNode("单元格是:" + i + j);
mycurrent_cell.appendChild(currenttext);
mycurrent_row.appendChild(mycurrent_cell);
// 如果在第0列设置单元格背景色
// 如果在第1列隐藏单元格
if (i == 0) {
mycurrent_cell.style.background = "rgb(255,0,0)";
} else {
mycurrent_cell.style.display = "none";
}
}
mytablebody.appendChild(mycurrent_row);
}
mytable.appendChild(mytablebody);
mybody.appendChild(mytable);
}
</script>
</html>