DOM编程-动态创建脚本、动态添加样式、DOM创建表格

DOM编程

动态脚本

动态脚本就是在页面初始加载时不存在,之后又通过 DOM 包含的脚本。
有两种方式通过<script>动态为网页添加脚本:

动态加载外部文件

<script src="foo.js"></script> 

可以像这样通过 DOM 编程创建这个节点:

let script = document.createElement("script"); 
script.src = "foo.js"; 
document.body.appendChild(script); // 动态添加节点

在上面最后一行把<script>元素添加到页面之前,是不会开始下载外部文件的。

动态样式

与动态脚本类似,动态样式也是页面初始加载时并不存在,而是在之后才添加到页面中的。

CSS 样式在 HTML 页面中可以通过两个元素加载:
<link>元素用于包含 CSS 外部文件,而<style>元素用于添加嵌入样式。

第一种:
使用元素包含 CSS 外部文件:

<link rel="stylesheet" type="text/css" href="styles.css">

这个元素很容易使用 DOM 编程创建出来:

let link = document.createElement("link"); 
link.rel = "stylesheet"; 
link.type = "text/css"; 
link.href = "styles.css"; 
let head = document.getElementsByTagName("head")[0]; 
head.appendChild(link); // 动态添加样式

以上代码在所有主流浏览器中都能正常运行。注意应该把<link>元素添加到<head>元素而不是
<body>元素,这样才能保证所有浏览器都能正常运行。

第二种
使用<script>元素包含嵌入的 CSS 规则,例如:

<style type="text/css"> 
body { 
 background-color: red; 
} 
</style>

逻辑上,下列 DOM 代码会有同样的效果:

let style = document.createElement("style"); 
style.type = "text/css"; 
style.appendChild(document.createTextNode("body{background-color:red}")); 
let head = document.getElementsByTagName("head")[0]; 
head.appendChild(style);  // 动态添加样式

操作表格

表格是 HTML 中最复杂的结构之一。通过 DOM 编程创建<table>元素,通常要涉及大量标签,包括表行、表元、表题,等等。因此,通过 DOM 编程创建和修改表格时可能要写很多代码。假设要通过DOM 来创建以下 HTML 表格:

<table border="1" width="100%"> 
 <tbody> 
 <tr> 
 <td>Cell 1,1</td> 
 <td>Cell 2,1</td> 
 </tr> 
 <tr> 
 <td>Cell 1,2</td> 
 <td>Cell 2,2</td> 
 </tr> 
 </tbody> 
</table> 

下面就是以 DOM 编程方式重建这个表格的代码:

// 创建表格
let table = document.createElement("table"); 
table.border = 1; 
table.width = "100%"; 
// 创建表体
let tbody = document.createElement("tbody"); 
table.appendChild(tbody); 
// 创建第一行
let row1 = document.createElement("tr"); 
tbody.appendChild(row1); 
let cell1_1 = document.createElement("td"); 
cell1_1.appendChild(document.createTextNode("Cell 1,1")); 
row1.appendChild(cell1_1); 
let cell2_1 = document.createElement("td"); 
cell2_1.appendChild(document.createTextNode("Cell 2,1")); 
row1.appendChild(cell2_1); 
// 创建第二行
let row2 = document.createElement("tr"); 
tbody.appendChild(row2); 
let cell1_2 = document.createElement("td"); 
cell1_2.appendChild(document.createTextNode("Cell 1,2")); 
row2.appendChild(cell1_2); 
let cell2_2= document.createElement("td"); 
cell2_2.appendChild(document.createTextNode("Cell 2,2")); 
row2.appendChild(cell2_2); 
// 把表格添加到文档主体
document.body.appendChild(table); 

以上代码相当烦琐,也不好理解。为了方便创建表格,HTML DOM 给<table>、<tbody>和<tr>
元素添加了一些属性和方法。
<table>元素添加了以下属性和方法:

caption,指向<caption>元素的指针(如果存在);
tBodies,包含<tbody>元素的 HTMLCollection;
tFoot,指向<tfoot>元素(如果存在);
tHead,指向<thead>元素(如果存在);
rows,包含表示所有行的 HTMLCollection;
createTHead(),创建<thead>元素,放到表格中,返回引用;
createTFoot(),创建<tfoot>元素,放到表格中,返回引用;
createCaption(),创建<caption>元素,放到表格中,返回引用;
deleteTHead(),删除<thead>元素;
deleteTFoot(),删除<tfoot>元素;
deleteCaption(),删除<caption>元素;
deleteRow(pos),删除给定位置的行;
insertRow(pos),在行集合中给定位置插入一行。
<tbody>元素添加了以下属性和方法:
rows,包含<tbody>元素中所有行的 HTMLCollection;
deleteRow(pos),删除给定位置的行;
insertRow(pos),在行集合中给定位置插入一行,返回该行的引用。
<tr>元素添加了以下属性和方法:
cells,包含<tr>元素所有表元的 HTMLCollection;
deleteCell(pos),删除给定位置的表元;
insertCell(pos),在表元集合给定位置插入一个表元,返回该表元的引用。

使用这些方法重写前面的代码:

// 创建表格
let table = document.createElement("table"); 
table.border = 1; 
table.width = "100%"; 
// 创建表体
let tbody = document.createElement("tbody"); 
table.appendChild(tbody); 
// 创建第一行
tbody.insertRow(0); // 创建第一行
tbody.rows[0].insertCell(0); // 创建表元并放在第一行第一个位置
tbody.rows[0].cells[0].appendChild(document.createTextNode("Cell 1,1")); // 引用第一行第一个表元,并添加文本子节点
tbody.rows[0].insertCell(1); // 创建表元并放在第一行第二个位置
tbody.rows[0].cells[1].appendChild(document.createTextNode("Cell 2,1")); // 引用第一行第二个表元,并添加文本子节点
// 创建第二行
tbody.insertRow(1); 
tbody.rows[1].insertCell(0); 
tbody.rows[1].cells[0].appendChild(document.createTextNode("Cell 1,2")); 
tbody.rows[1].insertCell(1); 
tbody.rows[1].cells[1].appendChild(document.createTextNode("Cell 2,2")); 
// 把表格添加到文档主体
document.body.appendChild(table);

使用NodeList

NodeList 就是基于 DOM 文档的实时查询。例如,下面的代码会导致无穷循环:

let divs = document.getElementsByTagName("div"); 
for (let i = 0; i < divs.length; ++i){ 
 let div = document.createElement("div"); 
 document.body.appendChild(div); 
} 

第一行取得了包含文档中所有<div>元素的 HTMLCollection。因为这个集合是“实时的”,所以
任何时候只要向页面中添加一个新<div>元素,再查询这个集合就会多一项。

因为浏览器不希望保存每次创建的集合,所以就会在每次访问时更新集合。这样就会出现前面使用循环的例子中所演示的问题。
每次循环开始,都会求值 i < divs.length。这意味着要执行获取所有<div>元素的查询。因为循环
体中会创建并向文档添加一个新<div>元素,所以每次循环 divs.length 的值也会递增。因为两个值
都会递增,所以 i 将永远不会等于 divs.length

任何时候要迭代 NodeList,最好再初始化一个变量保存当时查询时的长度,然后用循环变量与这
个变量进行比较,如下所示:

let divs = document.getElementsByTagName("div"); 
for (let i = 0, len = divs.length; i < len; ++i) { 
 let div = document.createElement("div"); 
 document.body.appendChild(div); 
} 

在这个例子中,又初始化了一个保存集合长度的变量 len。因为 len 保存着循环开始时集合的长度,而这个值不会随集合增大动态增长,所以就可以避免前面例子中出现的无穷循环。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值