由于浏览器中充斥着隐藏陷阱和不兼容问题,用JavaScript代码处理DOM的某些部分要比处理其他部分更复杂,操作DOM并不像表面上看起来那么简单。
动态脚本
使用< script>元素可以向页面中插入JavaScript代码,
一种方式是通过其src特性包含外部文件;
另一种方式就是用这个元素本身来包含代码。
动态脚本,指的是在页面加载时不存在,但将来的某一时刻通过修改DOM动态添加的脚本。
添加动态脚本有两种方式:插入外部文件和直接插入JavaScript代码。
动态加载的外部JavaScript文件能够立即运行:
<script type = "text/javascript" src = "client.js"></script>
创建节点的DOM代码:
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "client.js";
// <script>元素添加到页面中之前,是不会下载外部文件的
document.body.appendChild(script);
封装函数:
function loadScript(url){
var script = document.createElement("script");
script.type = "text/javascript";
script.src = url;
document.body.appendChild(script);
}
通过调用这个函数来加载外部的JavaScript文件:
loadScript("client.js")
加载完成后,即可使用这个脚本,问题为:怎么知道脚本加载完成呢,取决于所用浏览器。
另一种指定JavaScript代码的方式是行内方式:
<script type = "text/javascript">
function sayHi(){
alert("hi");
}
</script>
动态样式
把CSS样式包含到HTML页面中的元素有两个:<link>
与<style>
。
<link>
元素用于包含来自外部的文件,<link>
元素要添加到<head>
中;
function loadStyle(url){
var link = document.createElment("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = url;
var head = document.getElementsByTagName("head")[0];
head.appendChild(link);
}
//调用loadStyle()函数的代码
loadStyles("style.css")
<style>
元素用于指定内嵌的样式。
<style type = "text/css">
body{
background-color:red;
}
</style>
DOM代码
var style = document.createElement("style");
style.type = "text/css";
style.appendChild(document.createTextNode("body{background-color:red}"));
var head = document.getElementsByTagName("head")[0];
head.appendChild(style);
在Firefox、Safari、Chrome、Opera中运行,在IE中则会报错。
var style = document.createElement("style");
style.type = "text/css";
try{
style.appendChild(document.createTextNode("body{background-color:red}"));
}catch(ex){
style.styleSheet.cssText = "body{background-color:red}";
}
var head = document.getElementsByTagName("head")[0];
head.appendChild(style);
重写try-catch语句来捕获IE抛出的错误,然后再针对IE的特殊方式来设置样式:
function loadStyleString(css){
var style = document.createElement("style");
style.type = "text/css";
try{
style.appendChild(document.createTextNode(css));
}catch(ex){
style.styleSheet.cssText = css;
}
var head = document.getElementsByTagName("head")[0];
head.appendChild(style);
}
//调用这个函数
loadStyleString("body{background-color:red}");
实时地向页面中添加样式,能够马上看到变化。
操作表格
<table>
元素是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方法创建元素:
//创建table
var table = document.createElement("table");
table.border = 1;
table.width = "100%"
//创建tbody
var tbody = document.createElement("tbody");
table.appendChild(tbody);
//创建tr
//第一行
var row1 = document.createElement("tr");
tbody.appendChild(row1 );
//创建td
var ce111_1 = document.createElement("td");
ce111_1 .appendChild(document.createTextNode("Cell 1,1"));
row1.appendChild(ce111_1);
var ce112_1 = document.createElement("td");
ce112_1 .appendChild(document.createTextNode("Cell 2,1"));
row1.appendChild(ce112_1);
//第一行
var row2 = document.createElement("tr");
tbody.appendChild(row2 );
//创建td
var ce111_2 = document.createElement("td");
ce111_2 .appendChild(document.createTextNode("Cell 1,2"));
row1.appendChild(ce111_2);
var ce112_2 = document.createElement("td");
ce112_2 .appendChild(document.createTextNode("Cell 2,2"));
row1.appendChild(ce112_2);
//将表格添加到主体中
document.body.appendChild(table);
为<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) | 向rows集合中的指定位置插入一行 |
为<tbody>
元素添加的属性和方法:
方法 | 功能 |
---|---|
rows | 保存着对<tbody> 元素中行的HTMLCollection |
deleteRow(pos) | 删除指定位置的行 |
insertRow(pos) | 向rows集合中的指定位置插入一行,返回对新插入行的引用 |
为<tr>
元素添加的属性和方法:
方法 | 功能 |
---|---|
cells | 保存着对<tr> 元素中单元格的HTMLCollection |
deleteCell(pos) | 删除指定位置的单元格 |
insertCell(pos) | 向cells集合中的指定位置插入单元格,返回对新插入单元格的引用 |
重写代码如下:
// 创建table
var table = document.createElement("table");
table.border = 1;
table.width = "100%"
// 创建tbody
var tbody = document.createElement("tbody");
table.appendChild(tbody);
// 创建tr
// 第一行
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(有顺序的节点列表)及其“近亲”NamedNodeMap(无顺序列表节点)和HTMLCollection( HTML 元素的集合,提供了可以遍历列表的方法和属性),从整体上理解DOM的关键所在。
这三个值都是动态的,每当文档结构变化时,值都会更新.
//取得文档中所有的<div>元素的HTMLCollection.
// divs集合是“动态的”
var divs = document.getElementsByTagName("div"),
i,
div;
//每次循环都要对divs.length求值,每次循环都会创建一个新<div>,这个<div>也会被添加到集合中。
//无线循环
for(i = 0; i < divs.length; i++){
div = document.createElement("div");
document.body.appendChild(div);
}
var divs = document.getElementsByTagName("div"),
i,
len,
div;
//另设一个值存放length
for(i = 0, len = divs.length; i < len ; i++){
div = document.createElement("div");
document.body.appendChild(div);
}
DOM是语言中立的API,用于访问和操作HTML和XML文档。DOM1级将HTML和XML文档形象的看做一个层次化的节点树,可以使用JavaScript来操作节点树,进而改变底层文档的外观和结构。
DOM对性能的影响,往往是JavaScript程序中开销最大的部分,而因访问NodeList导致的问题为最多。NodeList对象都是“动态的”,这就意味着每次访问NodeList对象,都会运行一次查询,最好的办法就是尽量减少DOM操作。