第十章 DOM
10.1 node类型(共12种,任何节点必居其一)
(1)、node12种类型
Node.ELEMENT_NODE(1); | Node.PROCESSING_INSTRUCTION_NODE(7); |
Node.ATTRIBUTE_NODE(2); | Node.COMMENT_NODE(8); |
Node.TEXT_NODE(3); | Node.DOCUMENT_NODE(9); |
Node.CDATA_SECTION_NODE(4); | Node.DOCUMENT_TYPE_NODE(10); |
Node.ENTITY_REFERENCE_NODE(5); | Node.DOCUMENT_FRAGMENT_NODE(11); |
Node.ENTITY_NODE(6); | Node.NOTATION_NODE(12); |
(2)、判断节点类型(与数值作比较)
if (someNode.nodeType == Node.ELEMENT_NODE){ //在 IE 中无效
alert("Node is an element.");
}
//由于 IE 没有公开 Node 类型的构造函数,因此上面的代码在 IE 中
会导致错误,为了确保跨浏览器兼容,最好还是将 nodeType 属性与数字值进行比较
if (someNode.nodeType == 1){ //适用于所有浏览器
alert("Node is an element.");
}
(3)、NODE节点 七个属性 一个常用方法
1、childNodes属性
每个节点都有一个childNodes属性,其中保存着一个类数组对象NodeList,其保存着一组有序节点,是基于DOM结构动态执行查询的结果,可通过位置访问,但其非Array实例,访问方法 =》
var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;
2、parentNode属性
3、previousSibling属性
4、nextSibling属性
5、firstChild属性
6、lastChild属性
7、ownerDocument属性:该属性指向表示整个文档的文档节点,该关系表示的事任何节点都属于他所在的文档,任何节点都不能同时存在于两个或或者更多个文档中(!!!)
8、hasChildNodes( )方法:返回true或false
(4)、将NodeList对象转换为数组(arguments 对象使用 Array.prototype.slice()方法可以将其转换为数组)(!!!)
//由于IE8及IE8-将NodeList实现为一个COM对象,所以不能像使用JScript对象那样使用这种对象,所以下面这种方法在IE会报错
var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes,0);
//若想在IE将NodeList 转换为数组,必须手动枚举所有成员
function convertToArray(nodes){
var array = null;
try {
array = Array.prototype.slice.call(nodes , 0); //针对非IE
} catch (ex){
array = new Array();
for (var i=0,len=nodes.length; i < len; i++){
array.push(nodes[i]);
}
}
return array;
}
(5)、操作DOM节点的六个方法
1、appendChild( )方法:接受一个参数,用于向childNodes列表的末尾添加一个节点
2、 insertBefore( )方法:
a、用于将节点放在childNodes列表中某个特定的位置上而非末尾
b、接受两个参数:要插入的节点和 作为参照的节点,插入节点后被插入的节点会变成参照节点的前一个同胞节点,同时被方法返回,若参照节点是null,则insertBefore()与appendchild()执行相同的操作
3、replaceChild( )方法:
a、用于替换节点
b、接受两个参数:要插入的节点和 要替换的节点
c、要替换的节点将由这个方法返回并从文档树中移除
4、removeChild( )方法:
a、用于移除节点
b、接受一个参数:要移除的节点
c、要替换的节点将由这个方法返回并从文档树中移除
5、cloneChild( )方法:
a、用于创建调用这个方法的节点一个完全相同的副本
b、接受一个参数:布尔值
c、若参数为true:
(1)、执行深复制
(2)、复制节点及整个子节点树
d、若参数为false(默认):
(1)、执行浅复制
(2)、即只复制节点本身
(3)、复制后返回的节点副本属于文档所有,但并为其指定父节点,因此该节点副本就是一个“孤儿”,除非通过 appendChild()、 insertChild() 或 replaceChild()将他添加到文章中
//注:cloneNode() 方法不会复制添加到DOM节点中的JavaScript属性,例如事件处理程序,该方法只复制特性、(在 明确指定的情况下也复制)子节点其他一切都不会复制,IE存在一个BUG,即他会复制事件处理程序,所以建议在复 制之前最好移除事件处理程序
6、normalize( )方法:
a、作用:处理文档树中的文本节点
b、当在某节点的上调用该方法时就会在该节点的后代节点中查找这两种情况,
(1)、若找到空本文节点,则删除;
(2)、若找到相邻的文本节点,则将它们合并为一个文本节点
10.1.2 Document 类型
(1)、Document 类型特点
a、Javascript通过Document 类型表示文档;
b、在浏览器中,document对象是HTMLDocument(继承自Document)的一个实例,表示HTML页面,同时document对象是window对象的一个属性,因此可以作为全局对象来访问;
c、Document类型可以表示HTML页面或者其他基于XML的文档,不过最常见的应用还是作为HTMLDocument实例的Document对象。通过该文档对象,不仅可以取得与页面有关的信息,而且还能操作页面的外观及其底层结构;
d、在FireFox Safari Chrome Opera中,可以通过脚本访问Document类型的构造函数和原型,但是在所有的浏览器中都可以访问HTMLDocument类型的构造函数和原型
特征:
nodeType | 值为9 |
nodeName | 值为"#document" |
nodeValue | 值为null |
parentNode | 值为null |
ownerDocument | 值为null |
其子节点 | DocumentType(最多一个),Element(最多一个),ProcessingInstruction、Comment |
(2)、文档的子节点
a、两个内置的快捷访问Document节点的子节点的方式
(1)、documentElement属性:该属性始终指向<html>元素;(all)
(2)、childNodes属性
var html == document.documentElement; //取得<html>
alert(html === document.firstNode); //true
alert(html === document.childNodesp[0]); //true
b、body属性:指向<body>元素;(all)
c、doctype属性:访问<!DOCTYPE>访问其信息;(浏览器的支持差别很大)
d、多数情况下我们都用不着在document对象上面调用appendChild()、removeChild()、replaceChild()方法,因为文档类型(如果存在的话)是只读的
(3)、文档信息
a、title属性:document.title 访问或修改页面的title属性
b、网页的请求相关的三个属性
URL | URL属性中包含页面完整的URL(即地址栏的) | var url = document.URL |
domain | 页面的域名 | 不能从松散(loose)设置为紧绷(tight) |
referrer | 链接到当前页面的页面的URL |
(4)、查找元素
a、getElementById()
b、getElementById();
c、getElementsByClassName();
d、getElementsByTagName():返回包含HTMLCollection 对象,作为一个“动态”集合,于NodeList对象类似,可以使用方括号语法或者item()方法访问;
- HTMLCollection对象有一个方法,叫做nameItem(),该方法可以通过元素的name特性取得集合中的项;
<img src="myimage.gif" name="myImage">
var myImage = images.nameItem("myImage"); //语法一
var myImage = images["myImage"]; //语法二
(语法一二相同)
- getElementsByName():HTMLDocument类型才有的方法,返回HTMLCollection集合,nameItem()只返回第一项;
(5)、特殊集合
除了属性和方法,document对象还有一些特殊的集合,这些集合都是HTMLCollection对象的
document.anchors | 包含文档中所有带name特性的<a>元素 |
document.forms | 包含文档中所有的<form>元素,与document.getElementsByTagName("form")结果相同 |
document.images | 包含文档中所有的<img>元素,与document.getElementsByTagName("img")结果相同 |
document.links | 包含文档中所有带 href 特性的<a>元素 |
(6)、DOM一致性检测
document.implementation属性用于检测浏览器实现了DOM的哪些功能
DOM1级只为document.implementation规定了一个方法:hasFeature()
hasFeature():接受两个参数,要检测的DOM的名称和版本号
(hasFeature()方法返回ture并不意味着实现与规范一直,因此建议同时使用能力检测)
(7)、文档写入
write() | 原样写入 | 在浏览器加载过程中,可使用这两个方法动态的向页面加入内容 |
writeIn() | 相比write(),在末尾加了 \n | |
open() | 用于打开网页的输出流 | !!!还不会用 |
close() | 用于关闭网页的输出流 |
10.1.3 Element 类型
(1)、特点:
nodeType | 值为1 |
nodeName | 值为元素的标签名 |
nodeValue | 值为null |
parentNode | 可能是Document 或者Element |
子节点 | 可能是Element、Text、Comment、ProcessingInstruction、CDTASection、EntityReference |
(2)、nodeName属性和tagName返回相同值,但是由于HTML(标签名全部大写)XML(与源码一致),所以最好在比较之前将标签名转换为相同的大小写(toLowerCase() toUpperCase())
1、HTML元素
(1)、HTML元素标准特性(所有的特性都是属性)
id | 元素在文档中的唯一标识符 |
title | 有关元素的附加说明信息,一般通过工具提示条显示出来 |
className | 与元素的class特性对应,即为元素指定的CSS类 |
lang | 元素内容的语言代码 |
dir | 语言方向,ltr--从左到右; rtl--从右到左 |
(2)、所有的特性都是属性,所以可以直接给属性赋值设置特性的值,但是自定义属性不能这样序操作
div.id = "myId";
alert(div.getAttribute("id"));
2、操作特性三个方法(不区分大小写)
getAttribute() | 参数为实际属性名(如class而非className) |
setAttribute() | |
removeAttribute() | 删除特性及对应的特性值 |
3、attributes属性(可用于遍历元素特性)
a:Element类型是使用attributes属性的唯一一个DOM节点类型,attributes属性中包含一个NameNodeMap对象(动态集合)
b:NamedNodeMap:对象拥有以下方法
getNamedItem(name) | 返回nodeName属性等于name的节点 |
removeNamedItem(name) | 从列表移除nodeName属性等于name的节点 |
setNamedItem(node) | 向列表中添加节点,以节点的nodeName属性为索引;(不常用) |
item(pos) | 返回位于数字pos位置处的节点 |
c:有两类特殊的特性,他们虽然有对应的属性名,但是属性的值与通过getAttaribute() 返回的值并不相同
通过getAttribute()访问时 | 通过属性 | |
style | 返回的 style 特性值中包含的是 CSS 文本; | 通过属性来访问它则会返回一个对象 |
事件处理程序 (如onclick) | 返回相应代码的字符串; | JavaScript函数 |
d:迭代元素的没一个特性并并将其构造成name="value" name ="value"的字符串格式
function outputAttributes(element){
var pairs = new Array(),
attrName,
attrValue,
i,
len;
for (i=0,len=element.attributes.length;i < len; i++){
attrName = element.attributes[i].nodeName;
attrValue = element.attributes[i].nodeValue;
pairs.push(attrName + "=\"" + attrValue + "\"");
}
return pairs.join(" ");
}
4、创建元素
document.creatElement() 方法接受一个参数,要创建元素的标签名。还可以操作新元素的特性
var div = document.creatElement("div");
div.id = "myNewDiv"; //为新元素添加id特性
document.body.appendChild(div); //将新元素添加到文档的body元素中
5、元素的子节点
10.1.4 Text类型
1、特点
nodeType | 3 |
nodeName | "#Text" |
nodeValue | 节点所包含的文本 |
parentNode | 一个Element |
子节点 | 不支持 |
可以通过 nodeValue 属性或 data 属性访问 Text 节点中包含的文本,两个属性中包含的值相同; 对 nodeValue 的修改也会通过 data 反映出来,反之亦然。 操作文本节点中的文本 | |
appendData(text) | 将text添加到文本末尾 |
deleteData(offset,count) | 从offset指定的位置开始删除count个字符 |
inseteData(offset,text) | 从offset指定的位置插入text |
replaceData(offset,count,text) | 用text替换从offset指定的位置开始到offset+count为止处的字符串 |
splitText(offset) | 从offset指定的位置将当前文本节点分成两个文本节点 |
substringData(offset,count) | 提取从offset指定的位置开始开始到offset+count为止处的字符串 |
length属性 | nodeValue.length 和 data.length保存着相同的值 |
2、创建文本节点
语法:
document.createTextNode("<b>Hello World!</b>") | 接受一个参数(要插入节点的文本) |
3、方法:操控文本节点
合并相邻文本节点 | normalize() | 将两个文本节点合并为一个 |
分割文本节点 | splitText() | 按照指定的位置分割 nodeValue 值,返回指定位置之后的文本 |
10.1.5 Comment类型(注释)
1、特点
nodeType | 8 |
nodeName | "#comment" |
nodevalue | 注释的内容 |
parentNode | 可能是Document或Element |
子节点 | 没有(不支持)子节点 |
2、操作节点
拥有除了splitText()之外的所有字符串操作方法
10.1.6 CDATASection类型
10.1.7 DocumentType类型
10.1.8 DocumentFragment类型
10.1.9 Attr类型
1、特点
nodeType | 2 |
nodeName | 特性的名称 |
nodeValue | 特性的值 |
parentNode | null |
子节点 | 在HTMl中不支持(没有)子节点 在XML中子节点可以是Text或EntityReference |
2、三个属性
name | 特性名称,与nodeName的值相同 |
value | 特性的值(与nodeValue的值相同) |
specified | 布尔值(用于区分特性是在代码中指定的还是默认的) |
10.2 DOM操作技术
10.2.1 动态脚本
1、定义
页面加载时不存在,但是将来某一刻通过动态添加的脚本,创建动态脚本的两种方式:
a、插入外部文件
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "client.js";
b、直接插入JavaScript代码
10.2.2