DOM(文档队形模型)是针对HTML和XML文档的一个API(应用程序编程接口)。DOM描绘了一个层次化的节点树,允许开发人员添加,移除和修改页面的一部分。DOM可以讲任何HTML和XML文档描绘成一个有多层次节点构成的结构。节点分为几种不同的类型,每种类型分别表示文档中不同的信息。每个节点都拥有各自的特点、数据和方法,另外也与其他节点存在某种关系。节点之间的关系构成了层次,而所有页面标记则表现为一个以特定节点为根节点的树形结构。总共有12种节点类型,这些类型都继承自一个基类型-Node类型
Node类型
DOM1级定义了一个Node接口,Javascript中的所有节点类型都继承自Node类型,因此所有节点类型都共享着相同的基本属性和方法,每个节点都有一个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)
通过比较上面这些常量,可以很容易的确定节点的类型
1 if(someNode.nodeType == Node.ELEMENT_NODE){ //在IE中无效2 alert("Node is an element");3 }
为了确保跨浏览器兼容,最好还是将nodeType属性与数字值比较
1 if(someNode.nodeType == 1){ 2 alert("Node is an element");3 }
1、nodeName和nodeValue属性
要了解节点的具体属性,可以使用这两个属性,他们的值完全取决于节点的类型,在使用这两个值之前,最好是像下面这样先检测一下节点的类型
1 if(someNode.nodeType == 1){2 value = someNode.nodeName; //nodeName的值是元素的标签名3 }
2、节点关系
每个节点都有一个childNodes属性,其中保存着一个NodeList对象。NodeList是一种类数组对象,用于保存一组有序的节点,可以通过为止来访问这些节点。要注意他不是Array的实例,他实际上是基于DOM结构动态执行查询的结果,因此DOM结构的变化能够自动反映在NodeList对象中,要访问NodeList中的节点可以通过方括号,也可以使用item()方法,另外也与其他节点存在某种关系。节点之间的关系构成了层次,而所有页面标记则表现为一个以特定节点。
1 var fitstChild = sonmeNode.childNodes[0];2 var secondChild = someNode.childNodes.item(1);3 var count = someNode.childNodes.length;
在前面介绍过,对arguments对象使用Array.prototype.slice()方法可以将其转换为数组,对于NodeList也适用。
1 //在IE8及之前版本无效 2 var arrayOfNodes = Array.prototype.alice.call(someNode.childNodes,0); 3 4 //兼容所有浏览器 5 function converToArray(nodes){ 6 var array = null; 7 try{ 8 array = Array.prototype.slice.call(nodes,0); //针对非IE浏览器 9 }catch(ex){10 array = new Array();11 for(var i=0,len = nodes.length;i < len; i++){12 array.push(nodes[i]);13 }14 }15 return array;16 }
每一个节点都有一个parentNode属性,该属性指向文档树中的父节点。包含在childNodes列表中的所有节点都具有相同的父节点,因此他们的paternNode属性都指向同一个节点。此外包含在childNodes列表中的每个节点相互之间都是同胞节点。通过使用列表中每个节点的previousSibling和nextSibling属性,可以访问同一列表中的其他节点列表中第一个节点的previousSibling属性值为null,而列表中最后一个节点的nextSlbling属性的值同样也是null
父节点的firstChild和lastChild属性分别指向起childNodes列表中的第一个和最后一个节点。其中someNode.firstChild等于someNode.childNodes[0],而someNode.lastChild等于someNode.childNodes[someNode.childNodes.length - 1]
hasChildNodes()在节点包含一个或多个子节点的情况下返回true
所有节点都有的最后一个属性是ownerDocument,该属性指向表示整个文档的文档节点,通过这个属性,我们可以不必在节点层次中层层回溯到顶端,而是可以直接访问文档节点
3、操作关系
appendChild(),用于向childNodes列表的末尾添加一个节点,相应的指针关系会更新,更新完成后返回一个新增的节点。
1 var returnNode = someNode.appendChild(newNode);2 console.log(returnNode = someNode.firstChild); //true3 console.log(returnNode = newNode); //true
如果传入到appendChild()方法中的参数已经是文档中的一部分,则他会从原来的位置转移到新的位置,例如
1 var returnNode = someNode.appendChild(someNode.firstChild);2 console.log(returnNode = sonmeNode.firstChild); //false3 console.log(returnNode = someNode.lastChild); //true
insertBefore()把节点放在列表中某个特定的位置上。接受两个参数:插入的节点和作为参考的节点。插入的节点会作为参考节点的前一个同胞节点,同时被返回,如果参照节点是null,则和appendChild()相同
1 //插入后成为第一个节点2 returnNode = someNode.insertBefore(newNode,someNode.childNodes[0]);3 //插入后成为最后一个节点4 returnNode = someNode.insertBefore(newNode,someNode.lastChild);5 //插入到最后一个节点的前面6 returnNode = someNode.insertBefore(newNode,someNode.childNodes[someNode.childNodes.length - 1]);
replaceChild()替换某个节点,接受两个参数:插入的节点和要替换的节点。要替换的节点将由这个方法返回并从文档树中移除。
1 //替换第一个子节点2 var returnNode = replaceChild(newNode,someNode.firstChild);
removeChild()移除某个节点,接受一个参数即要移除的节点并返回它。
1 //移除第一个子节点2 var returnNode = removeChild(someNode.childNodes[0]);
4、其他方法
有两个方法是所有类型的节点都有的:cloneNode()和normalize()
cloneNode()方法接受一个布尔值参数,表示是否执行深复制,参数为true时,执行深复制。也就是复制节点本身和整个子节点树。参数为false时,执行浅复制即只复制节点本身。复制后返回的节点副本属于文档所有,但并没有为他指定父节点。因此,这个节点的副本就成为了一个“孤儿”,除非通过appendChild()、insertBefore()或replaceChild()将他添加到文档中,例如:
1 <ul> 2 <li></li> 3 <li></li> 4 <li></li> 5 </ul> 6 7 //如果我们已经将<ul>元素的引用保存在了myList中, 8 9 var deepList = myList.cloneNode(true);10 console.log(deepList.childNodes.length); //311 12 var shallowList = myList.cloneNode(false);13 concole.log(shallow.childNodes.length); //0
cloneNode()方法不会复制添加到DOM节点中的JavaScript属性,例如事件处理程序等。
normalize()唯一的作用就是处理文档中的文本节点,由于解析器的实现或者DOM操作等原因,可能会出现文本节点不包含文本,或者接连出现两个文本节点的情况。当在某个节点上调用这个方法时,就会在该节点中查照上述两种情况。如果找到了空文本节点,则删除它。如果找到相邻的文本节点,则将它们合并为一个文本节点。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。