DOM
DOM(文档对象模型)是针对HTML和XML文档的一个API。描绘了一个层次化的节点树,允许开发人员添加,修改和删除页面的某一个部分。
-
节点层次
- DOM可以将任何HTML或XML文档描绘成一个由多层节点构成的结构。
- 节点分为几种不同的类型。每种类型分别表示文档中不同的信息或标记。
- 每个节点都有各自的特点,方法和数据。
- 每个节点之间和其他节点之间存在某种关系。
- 节点之间的关系构成了层次,而所有页面标记则表现为一个以特定节点为根节点的树形结构。
- 文档节点是每个文档的根节点。
-
元素称为文档元素。文档元素是文档的最外层元素,文档中的其他所有元素都是包含在文档元素中。
- 每个文档都只能有一个文档元素。在HTML中,文档元素始终都是
元素。在XML中,没有预定义的元素,则任何元素都有可能是文档元素。
- 每一段标记都可以用树中的一个节点表示。
-
Node类型
- 这个Node接口在JavaScript中是作为Node类型实现的;除了IE外,在其他所有浏览器中都可以访问到这个类型。
- JavaScript中的所有节点类型都是继承自Node类型,因此,所有节点类型都共享相同的基本属性和方法。
- 每个节点都有一个nodeType属性,用于表示节点类型。节点类型由在Node类型中定义的下列12个数据常量表示,任何节点必居其一。
常量名 常量值 节点类型 描述 Node.ELEMENT_NODE 1 Element 代表元素 Node.ATTRIBUTE_NODE 2 Attr 代表属性 Node.TEXT_NODE 3 Text 代表元素或属性中的文本内容 Node.CDATA_SECTION_NODE 4 CDATASection 代表文档中的 CDATA 部(不会由解析器解析的文本) Node.ENTITY_REFERENCE_NODE 5 EntityReference 代表实体引用 Node.ENTITY_NODE 6 Entity 代表实体 Node.PROCESSING_INSTRUCTION_NODE 7 ProcessingInstruction 代表处理指令 Node.COMMENT_NODE 8 Comment 代表注释 Node.DOCUMENT_NODE 9 Document 代表整个文档(DOM 树的根节点) Node.DOCUMENT_TYPE_NODE 10 DocumentType 向为文档定义的实体提供接口 Node.DOCUMENT_FRAGMENT_NODE 11 DocumentFragment 代表轻量级的 Document 对象(文档的某个部分) Node.NOTATION_NODE 12 Notation 代表 DTD 中声明的符号 - 由于IE没有公开Node类型的构造函数,所以为了确保跨浏览器兼容问题,最好是将nodeType属性与数字值进行比较。
- 对于元素节点,nodeName中保存的值始终是元素的标签名(大写),而nodeValue的值始终为null。
- 对于属性节点的 nodeName 是属性名称,nodeValue 属性包含属性值。
- 对于文本节点的 nodeName 永远是 #text,nodeValue 属性包含文本。
- 节点关系
- 每个节点都有一个childNodes属性,返回一个NodeList对象。该对象是一个类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点。且该对象有length属性,但它不是Array的实例。该对象是基于DOM结构动态执行查询的结果,就是说DOM结构的变化会自动反映到该对象中。
- 每个节点都有一个parentNode属性,返回该节点的父节点。每个节点的previousSibling和nextSibling属性,分别返回该节点的上一个和下一个节点。
- 每个节点都有hasChildNodes()方法,这个方法在该节点包含一个或多个节点的情况下返回true。
- 每个节点都有一个ownerDocument属性,返回表示整个文档的文档节点。这种关系表示的是任何节点都属于它所在的文档,任何节点都不能同时存在于两个或多个文档中。
- 操作节点
- appendChild() 用于向childNodes列表的末尾添加节点。如果传入该方法中的节点是文档的一部分,那么该传入的节点就会被移动到新的位置。
- insertBefore() 用于向childNode列表中特定的位置添加节点。接收两个参数:要插入的节点和作为参照的节点,同时该方法被返回。插入的节点会被插入到参照节点的前一个位置。如果参照节点是null,那么效果等同于appendChild。
- replaceChild() 用于替换节点,接收两个参数:要插入的节点和替换的节点。要替换的节点将有这个方法返回并从文档树中剔除,同时由要插入的节点占据其位置。使用该方法插入一个节点时,该节点的所有关系指针都会从被他所替换的节点复制过来。替换的节点仍在文档中,但文档中没有其位置了。
- removeChild() 用于移除节点,接收一个参数:要移除的节点。被移除的节点成为该方法的返回值。移除的节点仍在文档中,但文档中没有其位置了。
- cloneNode() 用于创建调用该方法的节点的一个完全相同的副本。接收一个布尔值:表示是否执行深复制。在参数为true下,执行深复制,就是复制节点以及其整个子节点树,但是不会复制添加到DOM树节点中的JavaScript属性,如事件处理程序等(注意:IE中有一个BUG,它会复制事件处理程序,因此在复制之前最好移除事件处理程序);在参数为false下,执行浅复制,即只复制该节点,复制后的节点归文档所有,但并没有为他指定父节点,所以这个节点在文档中类似于“孤儿”。
-
Document类型
document对象是HTMLDocument的一个实例,表示整个HTML页面。document对象是window对象的一个属性,因此可以将其作为全局对象来访问。
-
Document节点有以下特征:
- nodeType的值为9
- nodeName的值为"#document"
- nodeValue的值为null
- parentNode的值为null
- ownerDocument的值为null
- 其子节点可能是一个DocumentType(最多一个),Element(最多一个),ProcessingInstruction或Comment
-
文档的子节点
- 访问document节点的html子节点内置的访问方法
- documentElement属性,该属性始终指向HTML页面中的
- 通过document.childNodes[0]列表来访问
- 通过document.firstChild来访问
- documentElement属性,该属性始终指向HTML页面中的
- document.body直接指向
元素
- document.doctype可以访问
元素,不同浏览器有差异
- IE8及之前的版本:如果存在文档类型声明,会将其错误的解释为一个注释并把它当成Comment节点;而document.doctype的值始终为null。
- IE9+以及Firefox:如果存在文档类型声明,则将其作为文档的第一个子节点;document.doctype是一个Document节点,也可以通过document.firstChild或document.childNodes[0]来访问同一个节点。
- Safari,chrome和Opera:如果存在文档类型声明,将其解析,但不作为文档的子节点。document.doctype是一个Document节点,但该节点不会出现在document.childNodes中。
-
元素外部的注释在不同浏览器中处理不同
- ie8及之前的版本,Safari 3.1及更高的版本,opera和chrome 只会为第一条注释创建节点,不为第二条注释创建节点。因此第一条注释会成为document.childNodes中的第一个节点、
- ie9及更高的版本,将第一条注释创建为document.childNodes中的一个注释节点,也将第二条注释创建为document.childNodes中的注释节点。
- Firefox以及Safari 3.1之前的版本会完全忽略这两条注释。
- 访问document节点的html子节点内置的访问方法
-
文档信息
- document.title 包含
元素中的文本,会显示在浏览器窗口的标题栏或标签页上。修改title属性值也会改变
元素。 - document.URL 包含页面完整的URL(即地址栏中显示的URL)。
- document.domain 只包含页面的域名。不能将这个属性值设置为URL中不包含的域。
- document.referrer 包含链接到当前页面的那个页面的URL。在没有页面来源的情况下,可能为空字符串。
- 解决跨域问题的一个方法:
- 由于跨域安全限制,来自不同子域的页面无法通过JavaScript通信。而将每个页面的document.domain设置为相同的值,那么这些页面就可以互相访问对方包含的JavaScript对象。
- 例如,一个页面加载自
www.wrox.com
,其中包含一个内嵌框架,这个内嵌框架的页面加载自p2p.worx.com
。如果将document.domain值都设置为"wrox.com",那么他们之间就能相互通信了。
- document.title 包含
-
查找元素
- document.getElementById() 接收一个参数:要取得的元素ID。如果找到相应的元素则返回该元素,如果不存在则返回null。注意ID必须严格匹配,包括大小写。如果页面中有多个元素的ID相同,返回第一次出现的元素。
- document.getElementByTagName() 接收一个参数:要取得的元素标签名,返回的是包含零个或多个元素的NodesList。在HTML文档中,返回的是HTMLCollection对象,类似于NodeList对象。
- HTMLCollection对象中的项访问方式
- 使用方括号中使用数值语法或item()
- 使用nameItem()方法,该方法接收的参数为要查找的元素的name属性值
- 使用方括号中使用查找的元素的name属性值
- 如果传入参数为*,则表示要获取全部标签,按照它们出现的先后顺序出现。
- HTMLCollection对象中的项访问方式
- document.getElementByName() 接收一个参数:要取得元素的name属性值,返回所有具有该name属性值的元素。
-
特殊集合
-
DOM一致性检测:检测浏览器实现了DOM的哪些部分,可以使用document.implementation.hasFeature()方法,该接收两个参数:要检测的DOM功能的名称和版本号。如果浏览器支持给定名称和版本的功能,则返回true,否则返回false。
-
文档写入
- document.write() 接收一个字符串参数,即要写入到输出流中的文本。可动态的向页面中加入内容
- document.writeln() 接收一个字符串参数,即要写入到输出流中的文本,但会在字符串的末尾加上一个换行符。可动态的向页面中加入内容
- document.open() 打开网页的输出流
- document.close() 关闭网页的输出流
-
Element类型
- 该类型用于表现XML或HTML元素,提供了对元素标签名,子节点及特性的访问。
- Element节点具有以下特征:
- nodeType的值为1
- nodeName的值为元素的标签名
- nodeValue的值为null
- parentNode的值为Document或Element
- 其子节点可能是Element,Text,Comment,ProcessiongInstruction,CADTASection或EntityReference
- 要访问元素的标签名,可以使用nodeName,也可以使用tagName
- HTML元素:任何元素的所有特性,都可以通过DOM元素本身的属性来直接访问。
- 所有HTML元素都由HTMLElement类型表示,不是直接通过这个联系,也是通过它的子类型来表示。HTMLElement类型直接继承自Element并添加了一些属性。添加的属性分别对应于每个HTML元素中都存在的下列标准特性。
- id,元素在文档中的唯一标识符
- title,有关元素的附加说明信息,一般通过工具提示条显示出来
- lang,元素的语言代码
- dir,语言的方向,值为"ltr"从左到右或"rtl"从右到左
- className,为元素指定的CSS类
- 所有HTML元素都由HTMLElement类型表示,不是直接通过这个联系,也是通过它的子类型来表示。HTMLElement类型直接继承自Element并添加了一些属性。添加的属性分别对应于每个HTML元素中都存在的下列标准特性。
- 取得特性:getAttribute() 接收一个参数:要取得的特性名
- 该方法也能获取到自定义特性
- 特性的名称是不区分大小写的,即"id"与"ID"是同一特性
- 当特性是style时,返回的是CSS文本
- 当特性是onclick这样的事件处理程序,返回相应代码的字符串
- 设置特性:setAttribute() 接收两个参数:要设置的特性名和值
- 如果特性已经存在,则会用指定的值替换现有的值;如果不存在,则新建该属性并赋值。
- 通过这个方法设置的特性名会被统一转换为小写形式。
- 删除特性:removeAttribute() 接收一个参数:即要删除特性的名称。会清除特性的值,也会将该特性从元素中彻底删除。
- attribute属性
- Element类型是使用attribute属性的唯一一个DOM节点类型。attribute属性中包含一个NameNodeMap,与NodeList类似。元素的每一个特性都由一个Attr节点表示,每个节点都保存在NameNodeMap对象中。该对象有以下方法:
- getNameItem(name):返回nodeName属性等于name的节点
- removeNameItem(name):从列表中删除nodeName属性等于name的节点,并返回被删除特性的attr节点
- setNameItem(node):向列表中添加节点,以节点的nodeName属性为索引
- item(pos):返回位于数字pos位置处的节点
- attribute属性中包含一系列节点,每个节点的nodeName就是特性的名称,而节点的nodeValue就是特性的值。
- 对于attribute对象中的属性,不同浏览器返回的顺序不同。这些特性在XML或HTML代码中的先后顺序,不一定与它们出现在attribute对象中的顺序一致。
- Element类型是使用attribute属性的唯一一个DOM节点类型。attribute属性中包含一个NameNodeMap,与NodeList类似。元素的每一个特性都由一个Attr节点表示,每个节点都保存在NameNodeMap对象中。该对象有以下方法:
- 创建元素:document.createElement() 接收一个参数:即要创建元素的标签名。这个标签名在HTML文档中不分大小写,但在XML文档中区分。
- 在IE中,可以在该方法中传入完整的元素标签,也可以包含属性。
- 一些问题可以通过传入完整的元素标签来解决:
- 不能设置动态创建的
元素的name特性
- 不能通过表单的reset()方法重设动态创建的
元素
- 动态创建的type特性值为"reset"的
元素重设不了表单
- 动态创建的一批name相同的单选按钮彼此毫无关系
- 不能设置动态创建的
-
Text类型
- 文本节点由Text类型表示,包含的是可以照字面解释的纯文本内容。纯文本内容可以包含转义后的HTML字符,但不能包含HTML代码。
- Text节点具有以下特征:
- nodeType的值为3
- nodeName的值为"#text"
- nodeValue的值为节点所包含的文本
- parentNode的值Element
- 不支持(没有)子节点
- 可以通过nodeValue属性或data属性来访问Text节点包含的文本,这两个属性中包含的值相同。
- 操作节点中的文本方法:
- appendData(text):将text添加到文本的末尾
- deleteData(offset,count):从offset指定的位置开始删除count个字符
- insertData(offset,text):在offset指定的位置插入text
- replaceData(offset,count,text):用text替换从offset指定的位置开始到offset+count为止处的文本
- spliceText(offset):从offset指定为止将当前文本节点分成两个文本节点
- substringData(offset,count):提取从offset指定的位置开始到offset+count为止处的字符串
- 文本节点还有length属性,保存节点中字符的数目。nodeValue.length和data.length保存相同的值。
- 在默认下,每个可以包含内容的元素最多只能有一个文本节点,而且必须有内容存在。
- 创建文本节点:document.createTextNode() 接收一个参数:要出入节点的文本或完整的HTML代码(含文本)。
- 如果两个文本节点是相邻的同胞节点,那么这两个节点的文本就会连接起来,中间不会有空格。
- 规范文本节点:如果一个父元素包含两个或多个文本节点,可以调用normalize()方法,将所有节点合并成一个节点,结果节点的nodeValue等于合并前每个文本节点的nodeValue值拼接的值。
- 分隔文本节点:spliceText(offset)将一个文本节点分割成两个文本节点,按照指定位置分隔nodeValue值。原来的文本节点将包含从开始到指定位置之前的内容,新节点包含剩下的文本。该方法返回一个新文本节点,该节点与原节点的parentNode相同。
-
Comment类型
- 注释在DOM中是通过Comment类型表示的。
- Comment节点具有以下特征:
- nodeType的值为8
- nodeName的值为"#comment"
- nodeValue的值为注释的内容
- parentNode的值Element或Document
- 不支持(没有)子节点
- Comment类型与Text类型继承自相同的类,因此它也拥有除splitText之外的所有字符串操作方法。
- 可以通过nodeValue或data属性来取得注释的内容。
- 使用document.createComment()并为其传递注释文本可以创建注释节点。
-
CDATASection类型
- 该类型只针对XML文档,表示的是CDATA区域。
- 与Comment类似,拥有除了拥有除splitText之外的所有字符串操作方法。
- 具有以下特征:
- nodeType的值为4
- nodeName的值为"#cdata-section"
- nodeValue的值为CDATA区域中的内容
- parentNode的值Element或Document
- 不支持(没有)子节点
- 在真正的XML文档中,可以使用document.createCDataSection()来创建CDATA区域,只需传入节点的内容即可。
-
DocumentType类型
- 在web浏览器中并不常用,仅有Firefox,safari和opera支持。
- 包含着与文档的doctype有关的所有信息,具有以下特征:
- nodeType的值为10
- nodeName的值为doctype的名称
- nodeValue的值为null
- parentNode的值Document
- 不支持(没有)子节点
- 在DOM1级中,DocumentType对象不能动态创建,而只能通过解析文档代码的方式创建。支持它的浏览器会把DocumentType对象保存在document.doctype中。
- DOM1级描述了DocumentType对象的三个属性:
- name 表示文档类型的名称
- entities 由文档类型描述的实体的NameNodeMap对象
- notations 由文档类型描述的符号的NameNodeMap对象
- 通常,浏览器中的文档使用的都是HTML或XHTML文档类型,所以entities和notations一般为空列表。
-
DocumentFragment类型
- 在所有节点类型中,只有DocumentFragment在文档中没有对应的标记。DOM规定文档片段是一种轻量级的文档,可以包含和控制节点,但不会像完整文档那样占用额外的资源。
- 具有以下特征:
- nodeType的值为11
- nodeName的值为"document-fragment"
- nodeValue的值为null
- parentNode的值null
- 其子节点可能是Element,Text,Comment,ProcessiongInstruction,CADTASection或EntityReference
- 创建文档片段,可以使用document.createDocumentFragment()方法,不需要传参。
- 文档片段继承了Node的所有方法,通常用于执行那些用于针对文档的DOM操作。
- 如果将文档中的节点添加到文档片段中,就会从文档树中删除该节点,也不会在浏览器中看到该节点。添加到文档片段中的新节点同样也不属于文档树。可以通过appendChild()或insertBefore()将文档片段中内容添加到文档树中。在将文档片段作为参数传递给这两个方法时,实际上只会将文档片段的所有子节点添加到相应位置上;文档片段永远不会成为文档树的一部分。
- 假设要为一个
元素添加列表项,如果逐个添加列表项,将会导致浏览器反复渲染新信息。为避免这个问题,可以先将列表项添加到文档片段中,然后一次性添加到文档中。
-
Attr类型
- 元素的特性在DOM以Attr类型表示。在所有浏览器中(包含IE8),都可以访问Attr类型的构造函数和原型。
- 从技术角度看,特性就是存在于元素的attributes属性中的节点。特性节点有以下特征:
- nodeType的值为2
- nodeName的值为特性的名称
- nodeValue的值为特性的值
- parentNode的值null
- 在HTML中不支持(无)子节点
- 在XML中子节点可以是text或EntityReference
- Attr对象的三个属性:
- name 特性名称,与nodeName值相同
- value 特性的值,与nodeValue值相同
- specified 布尔值,区别特性是在代码中指定的还是默认的
- 使用document.createAttribute()并传入特性名称可以创建新的特性节点。
- 将新创建的特性节点添加到元素中,必须使用元素的setAttributeNode()方法。添加特性后,可以通过以下方法来访问特性:attributes属性,getAttributeNode()方法或getAttribute()方法。其中,attributes属性,getAttributeNode()方法都会返回对应特性的节点,getAttribute()方法只会返回特性的值。
动态脚本是指页面加载时不存在,但将来的某一时刻通过修改DOM动态添加的脚本。创建的两种方式:插入外部文件和直接插入JavaScript代码。
动态样式是指页面加载时不存在的样式,页面加载完成后动态添加到页面中的。加载外部样式文件的过程时异步的,也就是加载样式和执行JavaScript代码的过程没有固定的次序。
-
操作表格
- 为
添加的属性和方法如下
属性和方法 说明 caption 保存着对
元素(如果有)的指针tBodies 是一个 元素的HTMLCollection
tFoot 保存着对 元素(如果有)的指针
tHead 保存着对 元素(如果有)的指针
rows 是一个表格中所有行的HTMLCollection createTHead 创建 元素,并将其放入到表格中,返回引用
createTFoot 创建 元素,将其放到表格中,返回引用
createCaption 创建
元素,将其放到表格中,返回引用deleteTHead 删除 元素
deleteTFoot 删除 元素
deleteCaption 删除
元素deleteRow(pos) 删除指定位置的行 insertRow(pos) 向rows集合中的指定位置插入一行 - 为
添加的属性和方法如下
属性和方法 说明 rows 保存着 元素中行的HTMLCollection
deleteRow(pos) 删除指定位置的行 insertRow(pos) 向rows集合中的指定位置插入一行,返回对新插入行的引用 - 为
添加的属性和方法如下 属性和方法 说明 cells 保存着 元素中单元格的HTMLCollection deleteCell(pos) 删除指定位置的单元格 insertCell(pos) 向cells集合中的指定位置插入一个单元格,返回对新插入单元格的 使用NodeList
- NodeList,NameNodeMap以及HTMLCollection这三个集合都是动态的,即每当文档结构发生变化时,它们都会得到更新。因此,它们始终会保存着最新,最准确的信息。
- 本质上,所有NodeList对象都是在访问DOM文档时实时运行的查询。
你可能感兴趣的:(第九章)
- 为
- 为
- 为