1. Node类型

1.1 什么是DOM

DOM是针对HTML和XML文档的一个API,它描绘了一个层次化的节点树,允许开发人员添加、移除和修改页面的某一部分。节点分为几种不同的类型,每种类型分别表示文档中不同的信息及标记,每个节点都拥有自己的特点、数据和方法,另外也与其他节点存在某种关系,节点之间的关系构成了层次,而所有页面标记则表现为一个以特定节点为根节点的树型结构。

1.2 Node

DOM1级定义了一个Node接口,该接口将由DOM中的所有节点类型实现。Node接口在JavaScript中是作为Node类型实现的,除IE外,其他所有浏览器都可以访问到这个类型。JavaScript中的所有节点类型都继承自Node类型,节点类型由在Node类型中定义的下列12个数值常量来表示:

1) Node.ELEMENT_NODE(1)

2) Node.ATTRIBUTE_NODE(2)

3) Node.TEXT_NODE(3)

4) Node.CDATA_SECTION_NODE(4)

5) Node.ENTITY_REFERENCE_NODE(5)

6) Node.ENTITY_NODE(6)

7) Node.PROCESSING_INSTRUCTION_NODE(7)

8) Node.COMMENT_NODE(8)

9) Node.DOCUMENT_NODE(9)

10) Node.DOCUMENT_TYPE_NODE(10)

11) Node.DOCUMENT_FRAGMENT_NODE(11)

12) Node.NOTATION_NODE(12)

通过比较上面这些常量,可以确定节点的类型,例如:

if (mynode.nodeType == Node.ELEMENT_NODE) {alert("Node is an element.");
}

但是IE没有公开Node类型的构造函数,因此为了兼容,最好使用数字比较,例如:

if (mynode.nodeType == 1) {alert("Node is an element.");
}

要了解节点的具体信息,可以使用nodeName和nodeValue两个属性,它们的值取决于节点的类型。对于元素节点,nodeName中保存的是元素的标签名,而nodeValue为null。

每个节点都有一个childNodes属性,其中保存着一个NodeList对象。NodeList是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点。虽然可以通过方括号来访问NodeList的值,而这个对象也有length属性,但它并不是Array的实例,例如:

var firstChild = mynode.childNodes[0];
var secondChild = mynode.childNodes.item(1);
var count = someNode.childNodes.length;

每个节点都有一个parentNode属性,该属性指向文档树中的父节点。包含在childNodes列表中的每个节点都有同一个父节点,且相互之间都是同胞节点。通过使用列表中每个节点的previousSibling和nextSibling属性,可以访问同一列表中的其他节点。列表中第一个节点的previousSibling和最后一个节点的nextSibling属性的值都是null。

hasChildNodes()方法在节点包含一或多个子节点时返回true,可以用以检测节点是否包含子节点。所有节点都有一个属性ownerDocument,该属性指向表示整个文档的文档节点,通过这个属性,我们可以不必在节点层次中回溯到达顶端,而是可以直接访问文档节点。

1.3 操作节点

DOM提供了一些操作节点的方法,最常用的是appendChild(),用于向childNodes列表的末尾添加一个节点,更新完成后,appendChild()返回新增的节点,例如:

var returnNode = mynode.appendChild(newNode);

如果传入到appendChild()中的节点已经是文档的一部分,那结果就会将该节点从原位置移到新位置。

如果需要把节点放在 childNodes列表中的某个特定的位置上,而不是末尾,可以使用insertBefore()方法。这个方法接受两个参数:要插入的节点和作为参照的节点。插入完成后,insertBefore()返回插入的节点,例如:

var returnNode = mynode.insertBefore(newNode, someNode);

如果参照节点是null,则insertBefore与appendChild()相同。

replaceChild()方法接受两个参数:要插入的节点和要替换的节点。被替换的节点将由这个方法返回并从文档树中被移除,同时要插入的节点占据其位置,例如:

var returnNode = mynode.replaceChild(newNode, someNode);

如果只要移除节点,可以使用removeChild()方法。这个方法接受一个参数,即要移除的节点,同时返回被移除的节点,例如:

var returnNode = mynode.removeChild(someNode);

以上四种方法操作的都是某个节点的子节点,要使用这几个方法必须先取得父节点,如果在不支持子节点的节点上调用这些方法,会导致错误。

有两个方法是所有类型的节点都有的。第一个是cloneNode(),用于创建调用这个方法的节点的一个完全相同的副本。cloneNode()方法接受一个布尔值参数,表示是否执行深复制,深复制即复制节点及其整个子节点树。复制后返回的节点副本属于文档,但没有父节点,尾须通过方法将它添加到文档中。

还有一个方法是normalize(),这个方法处理文档树中的文本节点。由于某些原因,文本节点可能不包含文本,或者接连出现两个文本节点。当在某个节点上调用这个方法时,就会在该节点的后代节点中查找这种情况,如果找到空文本节点,则删除它,如果找到相邻的文本节点,则合并它们。

2. Document类型

2.1 Document

JavaScript通过Document类型表示文档。在浏览器上,document对象是HTMLDocument(继承自Document类型)的一个实例,表示整个HTML页面。页且,document对象是window对象的一个属性,因此可以将其作为全局对象来访问。Document节点具有以下特征:

1) nodeType的值为9。

2) nodeName的值为"#document"。

3) nodeValue的值为null。

4) parentNode的值为null。

DOM标准规定Document节点的子节点可以是DocumentType、Element、ProcessingInstruction或Comment,还有一些内置的访问其子节点的快捷方式。

第一个是documentElement属性,它始终指向HTML页面中的<html>元素。还有一个body属性,指向<body>元素。所有浏览器都支持document.documentELement和document.body属性。

通常将<!DOCTYPE>标签看成一个与文档其他部分不同的实体,可以通过doctype属性(document.doctype)来访问它的信息。不同浏览器对doctype的支持差异很大。

作为HTMLDocument的一个实例,document对象还有一些标准的Document对象所没有的属性,这些属性提供了document对象所表现的网页的一些信息。其中第一个属性是title,包含着<title>元素中的文本。还有三个与对网页请求有关的属性:URL、domain和referrer。URL属性中包含页面完整的URL,domain属性只包含页面的域名,而referrer属性中则保存着链接到当前页面的那个页面的URL,在没有来源页面的情况下,referrer属性中可能包含空字符串。

这三个属性中只有domain属性是可设置的,但由安全方面的限制,并非可以给domain设置任何值,如果URL中包含一个子域名,如www.test.com,那么就只能将domain设置为test.com。不能将这个属性设置为URL中不包含的域。浏览器对domain属性还有一个限制,即如果域名一开始是“松散的”,那么不能将它再设置为“紧凑的”。例如将document.domain设置为test.com后,就不能再将其设置回www.test.com,否则会导致错误。

2.2 查找元素

取得元素的操作可以使用document的几个方法来完成,包括getElementById()和getElementsByTagName()等。

getElement()接受一个参数:要取得的元素的ID,如果找到相应元素则返回,否则返回null,例如:

var div = document.getElementById("mydiv");

注意ID必须与页面中的元素id属性严格匹配,包括大小写。但IE8及较低版本不区分大小写,如果页面中多个元素的ID值相同,getElementById()只返回文档中第一次出现的元素。IE7中如果表单元素的name属性与给定的ID匹配,也会被该方法返回。

另一个常用于取得元素引用的方法是getElementsByTagName()。这个方法接受一个参数,即要取得元素的标签名,而返回的是包含零或多个元素的集合,例如:

var images = document.getElementsByTagName("img");

这个方法会返回一个HTMLCollection对象,该对象与NodeList类似, 可以使用方括号语法或item()方法来访问其中的项,而元素的数量可以通过其length属性取得。HTMLCollection对象还有一个方法:namedItem(),使用这个方法可以通过元素的name属性取得集合中的项,例如:

var myimage = images.namedItem("myImage");

在提供按索引访问项的基础上,HTMLCollection还支持按名称访问项,对命名的项也可以使用方括号来访问。要取得所有的元素,可以向getElementsByTagName()中传入“*”。

第三个方法,也是只有HTMLDocument才有的方法,是getElementsByName()。这个方法会返回带有给定name属性的所有元素,例如:

var radios = document.getElementsByName("color");

getElementsByName()也会返回一个HTMLCollection对象。

2.3 特殊集合

除了属性和方法,document对象还有一些特殊的集合。这些集合都是HTMLCollection对象,为访问文档常用的部分提供了快捷方式,包括以下:

1) document.anchors: 包含文档中所有带name属性的<a>元素。

2) document.applets: 包含文档中所有的<applet>元素。

3) document.forms: 包含文档中所有的<form>元素。

4) document.images: 包含文档中所有的<img>元素。

5) document.links: 包含文档中所有带href属性的<a>元素。

2.4 一致性检测

由于DOM分为多个级别,因此检测浏览器实现了DOM的哪些部分就十分必要。document.implementation属性就为此提供相应信息和功能。DOM1级只为document.implementation规定了一个方法,即hasFeature()。这个方法接受两个参数:要检测的DOM功能的名称及版本号,如果浏览器支持对应的名称和版本,则返回true,例如:

var hasXMLDom = document.implementation.hasFeature("XML", "1.0");
可以检测的不同的值及版本号
功能 版本号 说明
Core 1.0、2.0、3.0 基本的DOM,用于描述表现文档的节点树。
XML 1.0、2.0、3.0 Core的XML扩展。
HTML 1.0、2.0 XML的HTML扩展。
Views 2.0 基于某些样式完成文档的格式化。
StyleSheets 2.0 将样式表关联到文档。
CSS 2.0 对层叠样式表1级的支持。
CSS2 2.0 对层叠样式表2级的支持。
Events 2.0 常规的DOM事件。
UIEvents 2.0 用户界面事件。
MouseEvents 2.0 由鼠标引发的事件。
MutationEvents 2.0 DOM树变化时引发的事件。
HTMLEvents 2.0 HTML4.01事件。
Range 2.0 用于操作DOM树中某个节围的对象和方法。
Traversal 2.0 遍历DOM树的方法。
LS 3.0 文件与DOM树之间的同步加载和保存。
LS-Async 3.0 文件与DOM树之间的异步加载和保存。
Validation 3.0 在确保有效的前提下修改DOM树的方法。

2.5 文档写入

document对象拥有将输出流写入到网页中的能力。这个能力体现在4个方法中:write()、writeln()、open()和close()。其中write()和writeln()方法都接受一个字符串参数,即要写入到输出流中的文本。write()会原样写入,而writeln()会在字符串末尾添加一个换行符,例如:

document.write("<strong>" + (new Date()).toString() + "</strong>");

此外,还可以使用write()和writeln()方法动态地包含外部资源,但是不能直接包含字符串"</script>",因为这会导致该字符串被解释为脚本块的结束,所以解决方案:

document.write("<script type=\"text/javascript\" src=\"file.js\"") + "</scr" + "ipt>";

如果在文档结束后再调用document.write(),那么在输出的内容将会重写整个页面。

3. Element类型

3.1 Element

除了Document类型之外,Element类型是Web编辑中最常用的类型。Element类型用于表现XML或HTML元素,提供了对元素标签名、子节点及属性的访问。Element节点具有以下特征:

1) nodeType的值为1。

2) nodeName的值为元素的标签名。

3) nodeValue的值为null。

4) parentNode可能是Document或Element。

要访问元素的标签名,可以使用nodeName属性,也可以使用tagName属性,这两个属性会返回相同的值,例如:

var div = document.getElementById("mydiv");
alert(div.tagName);
alert(div.nodeName);

在HTML中,标签名始终以大写表示,而XML中,标签名与源代码中的保持一致,假如不确定自己的脚本会在HTML还是XML中执行,可以在比较之前转换为相同的大小写。

3.2 HTML元素

所有HTML元素都由HTMLElement类型表示。HTMLElement类型直接继承自Element并添加了一些属性:

1) id: 元素在文档中的唯一标识符。

2) title: 有关元素的附加说明信息。

3) lang: 元素内容的语言代码。

4) dir: 语言的方向,值为"ltr"或"rtl"。

5) className: 与元素的class属性对应。

上述这些属性都可以用来取得或修改相应的属性值,例如:

var div = document.getElementById("mydiv");
alert(div.id);
alert(div.className);

3.3 取得和设置属性

每个元素都有一或多个属性,操作属性的DOM方法主要有三个:getAttribute()、setAttribute()和removeAttribute(),例如:

var div = document.getElementById("mydiv");
alert(div.getAttribute("id"));
alert(div.getAttribute("class"));

注意传递给getAttribute()的属性名与实际的属性名相同,比如class属性值,只有在通过对象属性访问时才使用className。如果给定名称的属性不存在,则返回null。

通过getAttribute()方法也可以取得自定义属性,属性的名称是不区分大小写的。有两类特殊的属性,虽然有属性名,但属性的值与通过getAttribute()返回的值并不相同。第一类是style,在通过getAttribute()访问时,返回的style属性值是CSS文本,而通过属性访问则会返回一个对象。第二类是类似

与getAttribute()对应的方法是setAttribute(),这个方法接受两个参数:要设置的属性名和值,如果属性已经存在,则会以指定的值替换现有的值,如果属性不存在,则创建该属性并设置相应的值,例如:

var div = document.getElementById("mydiv");
div.setAttribute("id", "myid");
div.setAttribute("class", "myclass");

通过setAttribute()方法即可以操作HTML属性也可以操作自定义属性。通过这个方法设置的属性名会被统一转换为小写形式。

可以直接给属性赋值,但不包括自定义属性,例如:

var div = document.getElementById("mydiv");
div.id = "myid";
div.class = "myclass";

removeAttribute()方法用于彻底删除元素的属性,调用这个方法不仅会清除属性的值,也会从元素中完全删除属性,例如:

var div = document.getElementById("mydiv");
div.removeAttribute("class");

3.4 attributes属性

Element类型是使用attributes属性的唯一一个DOM节点类型。attributes属性中包含一个NamedNodeMap,与NodeList类似,也是一个动态集合。元素中的每一个属性都由一个Attr节点表示,每个节点都保存在NamedNodeMap对象中,NamedNodeMap有以下方法:

1) getNamedItem(name): 返回nodeName属性等于name的节点。

2) removeNamedItem(name): 从列表中移除nodeName属性等于name的节点。

3) setNamedItem(node): 向列表中添加节点,以节点的nodeName属性为索引。

4) item(pos): 返回位于pos位置处的节点。

attributes属性中包含一系列节点,每个节点的nodeName就是属性的名称,而节点的nodeValue就是属性的值,例如:

var id = element.attributes.getNamedItem("id").nodeValue;
var id = element.attributes["id"].nodeValue;

调用removeNamedItem()直接删除给定名称的属性,例如:

var oldAttr = element.attributes.removeNamedItem("id");

setNamedItem()方法可以为元素添加一个属性,需要传入一个属性节点,例如:

element.attributes.setNamedItem(newAttr);

3.5 创建元素

使用document.createElement()方法可以创建新元素。这个方法只接受一个参数,即要创建元素的标签名。这个标签名在HTML中不区分大小写,而在XML中,则是区分大小写的,例如:

var div = document.createElement("div");

在IE中可以用另一个方式使用createElement(),为这个方法传入完整的元素标签,也可以包含属性,例如:

var div = document.createElement("<div id=\"mydiv\"></div>");

3.6 元素的子节点

元素可以有任意数目的子节点和后代节点,元素的childNodes属性中包含了它的所有子节点,这些子节点有可能是元素、文本节点、注释或处理指令。不同浏览器在对待这些节点方面存在不同。

<ul id="mylist"><li>Item 1</li><li>Item 2</li><li>Item 3</li>
</ul>

在IE中解析,<ul>元素会有3个子节点,分别是3个<li>元素。但在其他浏览器中,<ul>元素都会有7个元素,包括3个<li>元素和4个文本节点(<li>元素之间的空白)。

元素也支持getElementsByTagName()方法,在通过元素调用这个方法时,除了搜索起点是当前元素,其他与通过document调用这个方法相同。

4. Text类型

4.1 Text

文本节点由Text类型表示,包含的是可以照字面解释的纯文本内容。纯文本中可以包含转义后的HTML字符,但不能包含HTML代码。Text节点具有以下特征:

1) nodeType的值为3。

2) nodeName的值为"#Text"。

3) nodeValue的值为节点所包含的文本。

4) parentNode是一个Element。

5) 无子节点。

可以通过nodeValue属性或data属性访问Text节点中包含的文本,这两个属性包含的值相同。使用以下方法可以操作节点中的文本:

1) appendData(text): 将text添加到节点的末尾。

2) deleteData(offset, count): 从offset指定的位置开始删除count个字符。

3) insertData(offset, text): 在offset指定的位置插入text。

4) replaceData(offset, count, text): 用text替换从offset到offset+count处的文本。

5) splitText(offset): 从offset指定的位置将当前文本节点分成两个文本节点。

6) substringData(offset, count): 提取从offset到offset+count处的字符串。

除此之外,Text节点还有一个length属性,保存着节点中字符的数目,等同于nodeValue.length和data.length。

在默认情况下,每个可以包含内容的元素最多只能有一个文本节点,而且必须有内容。

4.2 创建文本节点

可以使用document.createTextNode()创建新文本节点,这个方法接受一个参数:要插入节点中的文本,例如:

var textNode = document.createTextNode("Hello World!");

一般每个元素只有一个文本节点,但在有些情况下可能包含多个文本节点,容易导致混乱,可以调用normalize()方法将相邻的文本节点合并,这个方法是由Node类型定义的。Text类型的splitText()方法与normalize()相反,这个方法将一个文本节点分成两个文本节点。

5. 其他类型

5.1 Comment类型

注释在DOM中是通过Comment类型表示的,Comment节点具有以下特征:

1) nodeType的值为8。

2) nodeName的值为"#comment"。

3) nodeValue的值是注释的内容。

4) parentNode可能是Document或Element。

5) 没有子节点。

Comment类型与Text类型继承自相同的基类,因此它拥有除splitText()外所有字符串操作方法。与Text类型相似,可以通过nodeValue或data属性来取得注释的内容。

5.2 CDATASection类型

CDATASection类型只针对基于XML的文档,表示的是CDATA区域。与Comment类似,CDATASection类型继承自Text类型,因此拥有除splitText()外所有字符串操作方法。DATASection节点具有以下特征:

1) nodeType的值为4。

2) nodeName的值为"#cdata-section"。

3) nodeValue的值为CDATA区域中的内容。

4) parentNode可能是Document或Element。

5) 没有子节点。

CDATA区域只会出现在XML文档中,多数浏览器会把CDATA区域错误解析为Comment或Element。在XML中,可以使用document.createCDataSection()来创建CDATA区域,只需为其传入节点的内容。

5.3 DocumentType类型

DocumentType类型在Web浏览器中不常用,仅有Firefox、Safari和Opera支持。DocumentType包含着与文档的doctype有关的所有信息,它具有以下特征:

1) nodeType的值为10。

2) nodeName的值为doctype的名称。

3) nodeValue的值为null。

4) parentNode是Document。

5) 没有子节点。

5.4 DocumentFragment类型

在所有节点类型中,只有DocumentFragment在文档中没有对应的标记。DOM规定文档片段是一种“轻量级”文档,可以包含和控制节点,但不会占用额外资源。DocumentFragment节点具有以下特征:

1) nodeType的值为11。

2) nodeName的值为"#document-fragment"。

3) nodeValue的值为null。

4) praentNode的值为null。

5) 子节点可以是Element、ProcessingInstruction、Comment、Text、CDATASection或EntiryReference。

5.5 Attr类型

元素的属性在DOM中以Attr类型来表示。属性节点具有以下特征:

1) nodeType的值为11。

2) nodeName的值是属性的名称。

3) nodeValue的值是属性的值。

4) parentNode的值为null。

5) 在HTML中没有子节点。

6) 在XML中子节点可以是Text或EntityReference。

Attr对象有3个属性:name、value和specified。其中,name是属性名称,value是属性的值,specified是一个布尔值,用以区别属性是在代码中指定的,还是默认的。

转载于:https://blog.51cto.com/hanviseas/991048

[JavaScript] DOM相关推荐

  1. 六、前端开发-JavaScript DOM

    六.前端开发语言体系-JavaScript DOM 文章目录 六.前端开发语言体系-JavaScript DOM JavaScript DOM DOM简介 DOM方法 DOM事件 DOM事件监听器 D ...

  2. javascript DOM 遍历

    javascript DOM 遍历 由 愚人码头 撰写 http://www.css88.com/archives/514 javascript DOM 遍历 以下一系列的辅助函数可以帮助您,他们能取 ...

  3. javascript DOM(08-21)

    1.createElement()和createTextNode() //创建一个li新元素 var newChild=document.createElement('li'); //创建一个a 新元 ...

  4. html dom 替换节点,从javascript dom文本节点替换

    我正在使用javascript处理xhtml.我通过连接nodeType == Node.TEXT_NODE的所有子节点的nodeValue来获取div节点的文本内容.从javascript dom文 ...

  5. javascript dom追加内容的例子

    javascript dom追加内容的例子 javascript dom追加内容的使用还是比较广泛的,在本文将为大家介绍下具体的使用方法. 例子: <!DOCTYPE html PUBLIC & ...

  6. java svg 读取dom结构_SVG基础以及使用Javascript DOM操作SVG

    SVG 不依赖分辨率 支持事件处理器 最适合带有大型渲染区域的应用程序(比如谷歌地图) 复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快) 不适合游戏应用 Canvas 依赖分辨率 不支持事 ...

  7. JavaScript Dom编程艺术

    当我对JavaScript还停留在只认识这几个字母的时候,有一天我突然心血来潮,在网上下了DOM Scripting的样章,照着里面的例子写了我平生第一个能让我知所以然JavaScript,在浏览器运 ...

  8. html鼠标离开点击停留,Javascript DOM事件操作小结(监听鼠标点击、释放,悬停、离开等)...

    本文实例总结了Javascript DOM事件操作.分享给大家供大家参考,具体如下: 使用JavaScript可以对HTML页面上的各种事件进行监听,如鼠标点击/释放,鼠标悬停/离开,等等. 效果图: ...

  9. 高性能JavaScript DOM编程

    我们知道,DOM是用于操作XML和HTML文档的应用程序接口,用脚本进行DOM操作的代价很昂贵.有个贴切的比喻,把DOM和 JavaScript(这里指ECMScript)各自想象为一个岛屿,它们之间 ...

  10. Javascript——DOM编程

    Javascript--DOM编程 基本概述 文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标志语言的标准编程接口.DOM可以以一种独立于平台和语 ...

最新文章

  1. 程序员吐槽:去再好的互联网公司也就是个打工仔,还累出一身病
  2. Django:ORM关系字段
  3. C/C++协程实现-学习笔记
  4. NPOI读取Excel生成DataTable转为Json后利用LitJons读取
  5. js udp通信_nodejs源码分析第十九章 -- udp模块
  6. 计算机开机后黑屏 只有鼠标,开机黑屏只有鼠标
  7. mysql打错了怎么办_数据库出错了怎么办?
  8. [转载] Python类属性、类方法和静态方法
  9. QMC2:MAME 游戏仿照器
  10. OSPF的多域配置-要点总结
  11. perl:非贪婪的数量词
  12. 计算机期刊在线阅读,2010年计算机领域SCI收录期刊
  13. rovio论文解读,及工程应用经验总结
  14. 初中教师资格证科学计算机面试,2019上半年教师资格证面试真题:初中信息技术...
  15. PubWin服务器同步时间
  16. App工程结构搭建:几种常见Android代码架构分析
  17. 远程计算机或设备将不接受连接 解决方案
  18. 路由器桥接静态ip设置_如何在路由器上设置静态IP地址
  19. html页面显示代码插件,jQuery – 高亮动态显示页面HTML代码插件
  20. 计算机毕设结束语致谢,毕业设计结束语和致谢

热门文章

  1. java 改变文件路径_在C#中改变文件路径
  2. struts mysql乱码_Struts+Hibernate+MyEclipse+Tomcat+MySQL的乱码之解决
  3. java的常用注解有哪些_spring系列笔记之常用注解
  4. 刷爆推特的钢管舞机器人有~故~事
  5. Spark createDirectStream 维护 Kafka offset(Scala)
  6. 用keepalived配置高可用,监控NGINX服务
  7. nginx完全关闭log
  8. TightVNC进行远程控制
  9. 秘笈|如何利用DNS做好网络安全工作
  10. jQuery使用最广泛的javascript函数库