javascript高级程序设计笔记-第十章(DOM)
一、节点层次
1、节点类型
- 元素节点
- nodeType=1
- nodeName为标签名
- nodeValue为null
- parentNode为document或元素节点
- 子节点为元素节点或文本节点
- 属性节点
- nodeType=2
- nodeName为属性名
- nodeValue为属性值
- parentNode为null
- 在HTML中不支持子节点
- 文本节点
- nodeType=3
- nodeName为"#text"
- nodeValue为所包含的文本
- parentNode是一个元素节点
- 不支持子节点
1)、节点关系:
childNodes属性,保存着一个NodeList对象,它是一个类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点
//通过方括号和item()方法访问NodeList中的节点
var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;
parentNode属性,指向文档树中的父节点
previousSibling属性,指向同胞节点中的上一个节点
nextSibling属性,指向同胞节点中的下一个节点
列表中最后一个节点的和nextSibling属性和第一个节点的previousSibling属性的值为null
firstChild属性,父节点的childNodes列表中的第一个节点,类似于parentNode.childNodes[0]
lastChild属性,父节点的childNodes列表中的最后一个节点,类似于parentNode.childNodes[parentNode.childNodes.length-1]
hasChildNodes()方法,在节点包含子节点的情况下返回true
2)、操作节点:
appendChild()方法,向childNodes列表的末尾添加一个节点
insertBefore()方法,在某节点前面插入一个节点
replaceChild()方法,替换指定节点
removeChild()方法,移除指定节点
cloneNode()方法,参数为true时,执行深复制(复制节点及子节点树);false时,执行浅复制(只复制节点本身)
normalize()方法,如果是空文本节点,则删除它;如果是相邻的文本节点,则将它们合并为一个文本节点
2、document
var html = document.documentElement; //取得对html的引用
var body = document.body; //取得对body的引用
1)、文档信息:
var title = document.title; //取得文档标题
document.title = "new page title"; //设置文档标题
var url = document.URL; //取得完整的URL
var domain = document.domain; //取得域名
var referrer = document.referrer; //取得来源页面的URL
2)、查找元素:
getElementById()方法,返回该元素
getElementsByTagName()方法,返回一个HTMLCollection对象,类似NodeList
对于HTMLCollection,可以向方括号中传入数值或字符串形式的索引值。在后台,对数值索引就会调用item(),而对字符串索引就会调用namedItem()。
<img src="1.jpg" name="myImage">
var images = document.getElementsByTagName("img");
//数值索引
alert(images[0].src); //输出第一个图像的src属性值
alert(images.item(0).src); //同上
//字符串索引
alert(images["myImage"].src); //同上
alert(imagse.namedItem(myImage));//同上
3)、文档写入:
document.write(),接收一个字符串参数,表示要写入文档流中的文本
document.write("hello world");
//向文档流中添加文本
window.onload = function() {
document.write("hello world");
};
//重写文档
3、元素节点
getAttribute()方法,取得节点的属性,接收一个参数:该节点的属性名
setAttribute()方法,设置节点的属性,接收两个参数:属性名和属性值
removeAttribute()方法,移除节点的属性,接收一个参数:属性名
getAttribute()方法和setAttribute()方法可以通过使用对象的属性来替代
someNode.getAttribute("id");
someNode.setAttribute("class", "someOtherClass");
var myId = someNode.id;
someNode.class = "someOtherClass"
document.createElement()方法,创建新的元素节点
4、文本节点
document.createTextNode()创建文本节点
一般情况下,每个元素只有一个文本子节点,不过如果在同一个元素节点上,添加两次文本节点,就产生两个文本节点,这两个文本姐弟啊是相邻的同胞节点,其文本就会连接起来显示,中间不会有空格
var element = document.createElement("div");
element.className = "message";
var textNode = document.createTextNode("hello world!");
element.appendChild(textNode);
var anotherTextNode = document.createTextNode("Yeah!");
element.appendChild(anotherTextNode);
document.body.appendChild(element); //hello world!Yeah!
alert(element.childNodes.length); //2
在文本节点的父元素上调用normalize()方法,将文本节点合并成一个文本节点
element.normalize();
alert(element.childNodes.length); //1
splitText()方法,将一个文本节点分割成2个文本节点
var element = document.createElement("div");
element.className = "message";
var textNode = document.createTextNode("hello world!");
element.appendChild(textNode);
document.body.appendChild(element);
var newNode = element.firstChild.splitText(5);
alert(element.firstChild.nodeValue); //hello
alert(newNode.nodeValue); //world
alert(element.childNodes.length); //2
二、DOM操作技术
1、动态脚本
动态加载外部Javascript文件
function loadScript(url) {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = url;
document.body.appendChild(script);
}
动态加载内部Javascript代码
function loadScriptString(code) {
var script = document.createElement("script");
script.type = "text/javascript";
try {
script.appendChild(document.createTextNode(code)); //非IE
} catch (ex) {
script.text = code; //IE
}
document.body.appendChild(script);
}
loadScriptString("function sayHi() {alert('hi');}");
2、动态样式
动态加载外部css文件
function loadStyles(url) {
var link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = url;
var head = document.getElementsByTagName('head')[0];
head.appendChild(link);
}
动态加载内部css
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;}");
3、操作表格
//create table
var table = document.createElement("table");
table.border = 1;
table.width = "100%";
//create tbody
var tbody = document.createElement("tbody");
table.appendChild(tbody);
//create the first row
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 1.2"));
//create the second row
tbody.insertRow(1);
tbody.rows[1].insertCell(0);
tbody.rows[1].cells[0].appendChild(document.createTextNode("cell 2.1"));
tbody.rows[1].insertCell(1);
tbody.rows[1].cells[1].appendChild(document.createTextNode("cell 2.2"));
//add table to body
document.body.appendChild(table);
//出现在html中
<table border="1" width="100%">
<tbody>
<tr>
<td>cell 1.1</td>
<td>cell 1.2</td>
</tr>
<tr>
<td>cell 2.1</td>
<td>cell 2.2</td>
</tr>
</tbody>
</table>
4、使用NodeList
var divs = document.getElementsByTagName('div'),
i = 0,
div;
for (var i = 0; i < divs.length; i++) {
div = document.createElement("div");
document.body.appendChild(div);
}
上面代码会导致无限循环,因为第一行代码会取得文档中所有div元素的HTMLCollection。这个集合是动态的,当循环对条件divs.length求值时,会又一次查询所有div元素。而循环每次都会添加一个div,所有divs.length每次都在随循环递增,它们的值用于不会相等
var divs = document.getElementsByTagName('div'),
i = 0,
len,
div;
for (var i = 0 len = divs.length; i < len; i++) {
div = document.createElement("div");
document.body.appendChild(div);
}
上面代码,将length初始化为变量,只会访问一次divs.length