DOM
DOM是文档对象模型(Document Object Model),它是为文文档结构更改和查询提供的一系列API。通过这些API,我们可以对页面进行添加、移动或者更改节点,从而对调整页面结构。1998年,W3C发布了第一级的DOM规范。为基本的文档结构及查询提供了接口。
到目前为止,DOM被分为不同的部分(核心、XML、HTML)和级别(Level 1/2/3)
- Core DOM
定义了一套标准的针对任何结构化文档的对象 - XML Dom
定义了一套标准的针对XML文档的对象 - HTML DOM
定义了一套标准的针对HTML文档的对象
IE中Dom对象都是以CDom的形式实现的,所以和其他浏览器的实现会有一些差异。
节点层次
Dom会将结构性文档描绘成一个由节点形成的文档树。其中,节点又分为多种类型,每种类型代表文档中不同的信息。不同的节点之间的关系行了层次结构,由根节点向下延伸,形成了一棵完整的文档树。
每个文档都有一个根节点,为文档节点(document)。在文档节点之下,一般都会有
节点类型
DOM1级定义了一个Node接口,在js中作为Node类型实现,而且js中的所有节点类型都继承至Node类型。
常见的节点类型(及代表等级)有:
- 元素节点(ELEMENT_NODE 1)
- 属性节点(ATTRIBUTE_NODE 2)
- 文本节点(TEXT_NODE 3)
- 注释节点(COMMENT_NODE 8)
- 文档类型(DOCUMENT_NODE 9)
判断某节点的节点类型:
除了nodeType,还可以通过nodeName和nodeValue获得节点信息。
- 对于元素节点,nodeName就是标签名,nodeValue就是null
- 对于文本节点,nodeName是“#text”,nodeValue是文本字符串
节点关系
每个节点都有一个childNodes属性,它的值是一个类数组对象NodeList,里面保存了此节点的所有直接子元素。
这个对象也有length属性,但它并不是Array的实例。且它是在Dom结构上动态查询的结果,并不是一直不变的。
访问这个类数组可以用数组的方括号或者item方法。
每个节点拥有访问其他节点的几个属性:
- parentNode:指向父节点
- firstNode:指向childNodes列表中第一个子元素
- lastNode:指向childNodes列表中最后一个子元素
- previousSibling:指向前一个同胞(同级)元素
- nextSibling:指向后一个同胞元素
- ownerDocument:指向文档节点,即document
通过hasChildNodes()方法可以直接知道元素是否有子元素
操作节点
操作子节点的常用方法:
- appendchild():在节点的childNodes列表末尾插入一个节点,如果该节点已经存在,就会将该节点从原位置移至新位置
- insertBefore():把节点插入到指定位置,接收两个参数,要插入的节点及作为参照的节点,被插入的节点最后会置于同胞参照节点的前面。
- replaceChild():替换子节点,接收两个参数,要插入的节点和要替换的节点,并返回被替换的节点
- removeChild():移除子节点,将要移除的子节点作为参数,并作为返回值返回。
Document类型
Document类型有一个实例–documnet,它也作为全局对象被挂在window对象上。
document对象作为我们常用的一个对象,弄清楚它的方法属性是非常有必要的:
- childNodes:既然document也是一个节点,那么他也有所有节点共有的属性
- documentElement:指向文档中的html元素
- body:指向文档中的body元素
- doctype:取得对<!Doctype>的引用
- title:文档标题
- url:获取完整的url
- domain:取得域名(只能设置url中包含的域)
- referrer:取得来源页面的url
要注意domain,比如在页面中引入了一个框架且页面的域和此框架的域并不相同,那么这时他们是不能通信的,我们可以通过设置domai为相同域来实现通信。设置domain属性只支持从紧绷(mail.qq.com)到松散(qq.com),不支持重新设置为从松散都紧绷。
查找元素
下面是我们常见的集中获得元素索引的方法:
- getElementById():传入要获取元素的id
getElementsByTagName():传入要获取元素的标签名,返回包含零或多个元素的NodesList
- getElementsByTagName(*)会返回页面所有元素的集合,但在IE中会返回所有注释节点,因为它将注释实现为元素
getElementByName():HTMLDocument特有的方法,返回带有name特性的包含所有元素的HTMLCollection,可以通过namedItem()方法(可以在nodesList中获取特定name的项)来获取第一项
Element类型
元素类型(NodeType为1)算是我们最常用到的类型之一了,它提供了我们访问标签名、子节点及其他他行的途径。
它有以下特征:
- nodeType为1
- nodeName为标签名,也可用tagName获得
- nodeValue为null
- 子节点可能是Element、Text、Comment等
HTMLElement类型直接继承与Element类型,我们的所有HTML元素都是HTMLElemnt或者它的子类的实例,这些元素都有一些共有的属性:
- id 唯一标识符
- title 元素的附加说明,鼠标获取焦点会显示
- className 类名
获取及设置Attribute
操作特性主要有三个:
- getAttribute:获取指定特性的value
- setAttribute:传入设置的特性名及新设置的value
- removeAttribute:传入要移除的特性名
这些方法其实是在操作一个动态的NamedNodeMap,通过元素的Element.attributes我们可以访问它,我们可以通过操作attributes下的getNamedItem、setNamedItem等方法来实现统一的目的,只不过不是很方便就是了。
一般尽量少用这些方法,而是通过元素的属性直接去获取或者设置特性。
创建元素
通过document.createElement(tagName)方法我们可以创建一个元素,这时元素尚未添加到文档树中,我们通过appendchild()、insertBefore()、replaceChild()来进行插入。
IE下可以直接传入html字符串,如:
Text类型
文本节点可以包含转义后的HTML字符,但不能包含HTML代码,文本节点会作为父元素的第一个子元素,所以通过Element.childNodes[0]就可访问。
它有以下特征:
- nodeType为3
- nodeName为#text,也可用tagName获得
- nodeValue为文本
- 父节点是Element,不支持子节点
操作文本的方法:
- append():添加文本到末尾
- deleteData():传入offset(指定的位置),从这里开始删除count个字符
- insertData():在offset出入文本
- replace()
- splitText()
创建文本节点的方法:
document.createTextNode():传入文本内容,最后也需要插入到文档中才能生效
下一篇博客会介绍DOM的一些扩展和DOM2及DOM3的一些新增知识点。