DOM
一、什么是DOM?
文档对象模型简称为DOM,用于访问和操作html和XML文档的,DOM将html和xml文档看成是一个层次化的节点数,我们可以通过JavaScript来操作这些节点,从而改变底层文档的外观和结构。
文档节点是每个文档的根节点,文档节点只有一个子节点——HTML元素(文档元素)。
在html页面中,文档元素始终是html元素,在XML页面中,由于没有预定义的元素,因此任何元素都可能是文档元素。
html元素用元素节点表示,文本类型通过文档类型表示,特性通过特性节点表示……
总共有12种节点类型他们都继承自一个基类型——Node。
二、Node类型;
JavaScript中的所有节点类型都继承自Node类型,所以所有的节点都具有相同的基本属性和方法;
下面开始介绍这些基本属性和方法:
1、nodetype属性:表明节点的类型:
1:元素节点
2:属性节点
3:文本节点
4:CDATA区段
5:实体应用元素
6:实体
7:表示处理指令
8:注释节点
9:最外层的Root element,包括所有其他节点
10:<!DOCTYPE…>
11:文档碎片节点
12:DTD中声明的符号节点
注:这些属性值都是只读的无法修改,并且也不是所有的节点类型web浏览器都支持,最常用的是元素和文本节点;
2、nodeName和nodeValue属性:这两个属性都是表示元素节点的属性所以使用这个属性前应该检测一下节点类型
if(someNode.nodetype==1){
value=someNode.nodetype;
}
需要注意的是nodeValue的值始终是null;
3、节点关系:
文档中的所有节点之间都有这样或那样的关系,这种关系用传统的家族关系来描述。
每个节点都可以有一个childNodes属性,其中保存着一个隐式的NodeList对象。NodeList对象是一个类数组对象,用于保存一组有序节 点,可以象数组那样来通过为止来访问这些节点和调用length属性。
var firstChild=someNode.childNodes[0];
var secondChild=someNode.childNodes.item(1);
var num=someNode.childNodes.length;
//注意这里调用方法的不是NodeList而是childNodes
每个节点也都有一个 parentNode 属性,指向该节点的父节点。在 childNodes 列表中的所有子节点 parentNode 指向的都是同一个父节点。并且在 childNodes 列表中的字节点可以使用 perviousSibling 和 nextSibling 属性来访问前一个兄弟节点和后一个兄弟节点;
父节点的firstChild和lastChild表示的是childNodes列表中的第一个子节点和最后一个子节点;
另外 hasChildNodes()也是一个非常有用的方法——在某个节点包含一个子节点和多个子节点是返回true;
最后一个节点属性——ownerDocument,该属性指向表示整个文档的文档节点;
4、操作节点
由于上述的一些属性和方法都是只读的,所以DOM提供了一些操作节点的方法。
——appendChild()用于向childNodes列表的末尾添加一个节点;
——insertBefore()将节点添加到特定的位置上,第一参数是要插入的节点,第二个参数是参照的节点;
——replaceChild()替换某个节点,第一个参数是要插入的节点,第二个参数是要替换的节点;
——removeChild()接收一个参数,要移除的节点;
——cloneNode()创建一个完全一样的副本节点;通常要将这个副本节点添加到某个节点的childNodes列表中,否则就成了“孤儿”;
——normalize()处理文档树中的文本节点;
三、Document类型
作为HTMLDocument实例的document对象,不仅可以取得页面信息,操作页面的底层结构和外观。
1、 两个访问document子节点的快捷方式
——documentElement,该属性始终指向html元素;
——childNodes列表访问
2、文档信息:
document对象还提供了标准Document实例对象没有的属性
——title,
——url,
——domain,页面域名
——referrer,保存着链接当前页面的那个页面的url;
3、查找元素
这些方法都是保存在document对象里的
——getElementByID
——getElementByTagName
——getElementByname
4、特殊集合
除了一些属性和方法,documen对象还有一些特殊的集合
——document.anchors 包含文档中所有带name属性的a元素
——document.applets 包含文档中的所有applet元素
——documen.forms 包含文档中所有的form元素
——document.imags 包含页面中所有的img元素
——document.links 包含页面中所有的带href的a元素
5、文档写入
——write()
——writeln(),末尾会添加换行
——open()
——close()
四、Element类型
提供了对元素标签名,子节点和特性的访问,
1、获取标签名
nodeName属性,tagName属性
2、取得特性;
getAttribute()、setAttribute()、removeAtrribute();
3、创建元素
document.createElement ();
五、Text类型
文本节点由text类型表示,保函的是可以照字面意思解释的纯文本内容;
可以通过nodeValue来访问和修改文本内容;
1、创建文本节点
document.createTextNode();接收一个参数要插入节点中的文本;
2、规范化文本节点
normalize();
文档中如果存在两个同胞文本节点很容易导致混乱,如果在一个包含多个文本节点父元素上调用normalize()方法,则会将所有文本节点合并成一个文本节点。
splitText()是与normalize()相反的方法,可以分割文本节点;一个参数表示的是分割位置;
DOM操作技术
一、动态脚本
动态脚本指的是,在页面加载时不存在,但将来的某一时刻通过修改DOM动态添加的脚本;
动态创建脚本也有两种方式:插入外部文件和直接插入JavaScript代码
封装插入外部文件的方法:
function loadScript(url){
var script=document.createElement("script");
script.type="text/javascript";
script.src=url;
document.body.appendChild(script);
}
// 在别处调用
loadScript(index.js);
封装直接插入JavaScript代码的方法:
function loadScriptString(code){
var script=document.createElement("script");
script.type="text/javascript";
try{
script.appendChild(document.createTextNode(code));
}catch(ex){
script.text=code;
}
document.body.appendChild(script);
}
// 在别处调用
loadScriptString(function sayHi(){
alert("hello");
})
二、动态样式
脚本化css
插入外部css
function loadStyle(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);
}
// 调用函数
loadStyle("index.css");
直接插入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标签中而不是body标签中
head.appendChild(style);
}
// 在别处调用函数
loadStyleString("body{background-color:red}");
小结
DOM有各种节点构成,最基本的节点是Node,其他类型的节点都继承自Node;
理解DOM的关键就是理解DOM对性能的影响,DOM往往是JavaScript开销最大的部分,一般来说应该减少对NodeList的访问次数。