1 什么是DOM
DOM(文档对象模型)是针对 HTML 和 XML 文档的一个 API。 DOM1级将HTML和XML文档形象地看作一个层次化的节点树,可以使用JavaScript来操作这个节点树,进而改变底层文档的外观和结构。
2 DOM中的节点
DOM可以将任何HTML或XML文档描绘成一个由多层节点构成的结构。最基本的节点类型是Node,用于抽象地表示文档中一个独立的部分;所有其他类型都继承自
Node。
2.1 Node节点属性
每个节点都具有nodeType、nodeName、nodeValue属性。
(1)nodeType属性,用于表明节点的类型。节点类型由在Node 类型中定义的下列12个数值常量来表示:
- Node.ELEMENT_NODE(1);
- Node.ATTRIBUTE_NODE(2);
- Node.TEXT_NODE(3);
- Node.CDATA_SECTION_NODE(4);
- Node.ENTITY_REFERENCE_NODE(5);
- Node.ENTITY_NODE(6);
- Node.PROCESSING_INSTRUCTION_NODE(7);
- Node.COMMENT_NODE(8);
- Node.DOCUMENT_NODE(9);
- Node.DOCUMENT_TYPE_NODE(10);
- Node.DOCUMENT_FRAGMENT_NODE(11);
- Node.NOTATION_NODE(12)
Document类型表示整个文档,是一组分层节点的根节点。在JavaScript中, document 对象是Document 的一个实例。使用document对象,有很多种方式可以查询和取得节点。
Element节点表示文档中的所有HTML或XML元素,可以用来操作这些元素的内容和特性。
(2)nodeName 和nodeValue值取决于nodeType。对于元素节点,nodeName中保存的始终都是元素的标签名,而nodeValue的值则始终为null。
2.2 节点关系
属性 | 说明 |
---|---|
childNodes | 其中保存着一个NodeList对象。NodeList是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点(可以通过方括号,也可以使用 item()方法) |
parentNode | 指向文档树中的父节点 |
previousSibling | 当前节点的上一个兄弟节点 |
nextSibling | 当前节点的下一个兄弟节点 |
ownerDocument | 指向表示整个文档的文档节点 |
hasChildNodes()方法可以判断节点有没有子节点,在节点包含一或多个子节点的情况下返回true。
注意:
文档里几乎每一样东西都是一个节点。甚至连空格和换行都会被解释为节点,而它们也会全部包含在childNodes属性返回的数组当中。
2.3 节点操作方法
方法 | 说明 |
---|---|
appendChild() | 用于向childNodes列表的末尾添加一个节点。如果传入到appendChild()中的节点已经是文档的一部分了,那结果就是将该节点从原来的位置转移到新位置。比如传入第一个子节点,则该节点会变为最后一个子节点。 |
insertBefore() | 用于把节点放在childNodes列表中某个特定的位置上。两个参数:要插入的节点和作为参照的节点。 |
replaceChild() | 两个参数:要插入的节点和要替换的节点。要替换的节点将由这个方法返回并从文档树中被移除,同时由要插入的节点占据其位置。 |
removeChild() | 一个参数,即要移除的节点。被移除的节点将成为方法的返回值。 |
cloneNode() | 一个布尔值参数。在参数为true的情况下,执行深复制,也就是复制节点及其整个子节点树;在参数为false的情况下,执行浅复制,即只复制节点本身。复制后返回的节点副本属于文档所有,但并没有为它指定父节点。 |
normalize() | 处理文档树中的文本节点。当在某个节点上调用这个方法时,就会在该节点的后代节点中查找,如果找到了空文本节点,则删除它;如果找到相邻的文本节点,则将它们合并为一个文本节点。 |
3 Document节点
在浏览器中,document对象是HTMLDocument(继承自 Document 类型)的一个实例,表示整个HTML页面。而且,document对象是window对象的一个属性,因此可以将其作为全局对象来访问。
3.1 属性
body属性,直接指向<body>
元素;
title属性,包含着<title>
元素中的文本——显示在浏览器窗口的标题栏或标签页上;
URL属性,包含页面完整的 URL(即地址栏中显示的URL);
domain 属性,只包含页面的域名;
referrer属性,保存着链接到当前页面的那个页面的URL。在没有来源页面的情况下, referrer 属性中可能会包含空字符串。
3.2 方法
(1)获取节点
方法 | 说明 |
---|---|
getElementById() | 根据ID获取元素。ID必须与页面中元素的id特性(attribute)严格匹配,包括大小写。 |
getElementsByTagName() | 通过标签名获取元素,而返回的是包含零或多个元素的 NodeList |
getElementsByName() | 返回带有给定 name 特性的所有元素。只有 HTMLDocument 类型才有的方法。 |
getElementsByClassName() | 通过class来获取元素,返回元素对象数组 |
(2)文档写入
write()、 writeln()、 open()和 close()
使用 write()和 writeln()方法动态地包含外部资源,例如 JavaScript 文件等。在包含JavaScript 文件时,必须注意不能像下面的例子那样直接包含字符串</script>
,因为这会导致该字符串被解释为脚本块的结束,它后面的代码将无法执行。为避免这个问题,只需加入转义字符”\”即可。例如:
<script type="text/javascript">
document.write("<script type=\"text/javascript\" src=\"file.js\">" +"<\/script>");
</script>
4 Element节点
HTMLElement 类型直接继承自 Element 并添加了一些属性,所有 HTML 元素都由 HTMLElement 类型表示。HTMLElement 类型又有很多子类型,每一种子类型都有与之相关的特性和方法。
(1)有关特性的操作方法
getAttribute()
、setAttribute()
和 removeAttribute()
。
第一类特性就是style,用于通过CSS为元素指定样式。在通过getAttribute()访问时,返回的style特性值中包含的是CSS文本,而通过属性来访问它则会返回一个对象。
第二类与众不同的特性是onclick这样的事件处理程序。当在元素上使用时,onclick特性中包含的是JavaScript代码,如果通过getAttribute()访问,则会返回相应代码的字符串。而在访问onclick属性时,则会返回一个JavaScript函数(如果未在元素中指定相应特性,则返回null)。
(2)创建元素方法
使用document.createElement()
方法可以创建新元素。可以配合appendChild()
、 insertBefore()
或 replaceChild()
方法把新元素添加到文档树。
(3)元 素 也 支 持getElementsByTagName()
方法,结果返回当前元素的后代。
5 示例
<body>
<ul id="myList">
<li id="item1">item1</li>
<li id="item2">item2</li>
<li id="item3">item3</li>
<li id="item4">item4</li>
</ul>
<script>
var oUl = document.getElementById('myList');
oUl.nodeType; //1
oUl.nodeName; //UL
oUl.nodeValue; //null
var oLi = document.getElementById('item1');
oLi.nodeType; //1
oLi.nodeName; //LI
oLi.nodeValue; //null
//判断节点类型是否相同
oUl.nodeType==oLi.nodeType; //true
oLi.parentNode;
oLi.previousSibling;
oLi.nextSibling;
oLi.hasChildNodes(); //true oLi节点包含一个Text子节点
oLi.getAttribute('id'); //"item1"
//使用document.write()方法可以添加元素,但父节点只能是body标签
document.write("<li id=\"item5\">item5</li>");
//使用document.createElement()方法创建新的节点
var newLi = document.createElement('li');
newLi.id = "item6";
newLi.value = "item6";
//插入节点
oUl.appendChild(newLi);
//创建文本节点并插入到新创建的li节点下
var txt = document.createTextNode("item6");
newLi.appendChild(txt);
var anotherLi = document.createElement('li');
var txt1 = document.createTextNode("item7");
anotherLi.appendChild(txt1);
oUl.insertBefore(anotherLi,oLi);
</script>
</body>
最终的HTML页面: