javascript系列之DOM(一)

DOM基础详解
本文详细介绍了DOM(文档对象模型)的概念与发展历程,展示了如何利用DOM API进行网页元素的创建、检索和操作,包括创建DOM片段、遍历文档节点等实用技巧。
原文: javascript系列之DOM(一)

     DOM(document object moudle),文档对象模型。它是一个中立于语言的应用程序接口(API),允许程序访问并修改文档的结构,内容和样式。也就是一切语言(js,php 等)对web的操作是建立在DOM的基础之上的。行为的发生,首先必须获取文档中的一个对象作为其载体。

DOM发展史

     在漫长的互联网发展史上DOM一共经历了四个阶段。当前,我们正处在DOM 3阶段。

DOM 0 :不是W3C规范,只是Netscape Navigator 3.0 和 IE 3.0 中的等价功能性的定义。

DOM 1:专注于HTML和XML文档模型,提供了文档导航和处理功能。

DOM 2:在DOM 1的基础上提供了样式对象模型和事件模型。

DOM 3:在DOM 2的基础上规定了内容模型和文档验证,同时规定了文档加载和保存、文档查看、文档格式化和关键事件。

DOM关系图

 

HTML文档结构.jpg

      DOM眼中,html文档就是一个树形结构。也就是我们数据结构中的树。很显然document就是这个树的根节点。<html>下面有两个子(children)节点<head>,<body>。<head>,<body> 互为兄弟(sibling)。<table>,<span>,<p>是<body>的子节点, 是<html>的孙节点或后代(descendant)节点。

DOM节点对象

      HTML文档中各节点都是一个不同类型的节点(node)对象,每个节点都有自己的属性和方法。利用这些属性和方法我们就可以开始操作DOM了,包括遍历 整个文档树,获取含有某个属性的元素等等。当然DOM中有很多类型的节点,它是怎么样来区分它们的了?答案是nodeType。下面我们看看具体都有哪些 类型的节点

接口nodeType值备注
element1元素节点
text3文本节点
attr2节点属性
comment8注释节点
document9document
documentFragment11文档碎片

     在这些节点类型中,我们用的最多的就是元素(element)节点和文本(text)节点。Javascript操作HTML文档的时候,document即指向整个文档,<body><table>等节点类型即为Element至于这个nodeType,我们可以用它来检测节点类型。

     前面我们已经提到不同的节点提供了不同的属性和方法,现在具体每一个节点类型来看一下。document节点提供了一些常用的工厂方法,主要用于创建可以插入文档中各种类型的节点,详见下表:

方法描述
createElement创建元素节点
createTextNode创建文本节点
createAttribute创建属性节点
getElementById获取文档中指定id的元素节点
getElementsByTagName获取文档中指定标签的元素节点
getElementByName获取文档中指定名称的元素节点

 

    元素节点提供了一个tagName属性用来获取元素的标签名称(全为大写),提供的一些方法主要用来插入和删改,查询和设置元素。详见下表:

getAttribute以字符串的形式返回指定属性的值
getAttributeNode以Attr节点的形式返回指定属性
hasAttribute判断节点是否有指定名字属性
removeAttribute删除指定名字属性
setAttribute设置指定名字的属性,若没有,添加一个
 setAttributeNode 设置指定名字的属性节点

       Attr对象代表文档元素的属性,有name、value等属性,可以通过Node接口的attributes属性或者调用Element接口的 getAttributeNode()方法来获取。不过,在大多数情况下,使用Element元素属性的最简单方法是getAttribute()和 setAttribute()两个方法,而不是Attr对象。

      这些节点类型都是一个节点对象,而节点对象又定义了一些共有的属性和方法,以方便的操作DOM文档。用parentNode和 childrenNodes[]在文档中上下移动,用nextSibling在文档中左右移动。firstChild和lastChild可以枚举指定节 点的子节点,通过遍历childNodes[](这里的childNodes[]是一个nodeList对象)数组循环操作这些子节点,然后通过递归,可 以没举出文档树中所有节点。而调用 appendChild(),insertBefore(),removeChild(),replaceChild()方法可以改变一个节点的子节点从 而改变文档树。下面是一些Node对象的常用属性和方法。

Node对象的常用属性:

attributes若该节点是一个element,返回该元素的属性
childNodes返回当前元素的子节点,若没有,则为null
firstChild返回当前节点的第一个子节点。若没有,则为null
lastChild返回当前节点的最后一个子节点。若没有,则为null
nextSibling返回当前节点的下一个兄弟节点
nodeName返回当前节点的名字,element为标记名称
parentNode当前节点的父节点
previousSibling返回当前节点的上一个兄弟节点

 Node对象常用方法:

appendChild()把一个节点增加到当前节点的childNodes[],
cloneNode()复制当前节点,若参数为true,复制当前节点及它的所有子孙节点
hasChildNodes()判断当前节点是否拥有子节点
insertBefore()在指定节点和当前节点之间插入一个新的节点
removeChild()从文档中删除并返回指定子节点
replaceChild()从文档中删除并返回指定子节点,用另一个节点替换它

 

    上面列举出来的常用节点对象的属性和方法是我们操作DOM最有用的工具,接下来,就让我们使用上述的属性和方法来操作日常中所见的DOM行为。

DOM操作

A : 创建一段DOM片段(碎片),形如:

                   <div id=”example”>

                           <p class=”slogan”>淘!你喜欢</p>

                    </div>

 1 var fragment=document.createDocumentFragment();//创建文档碎片
 2 var oDiv=document.createElement("div");//创建div元素节点
 3 oDiv.setAttribute("id","example");//给div节点添加id 属性
 4 var oP=document.createElement("p");//创建p元素节点
 5 oP.setAttribute("class","slogan");//给p节点添加class属性
 6 var oText=document.createTextNode("淘!你喜欢")//创建文本节点
 7 oP.appendChild(oText);//给p元素节点添加文本节点
 8 oDiv.appendChild(op);
 9 fragment.appendChild(oDiv)
10 document.body.appendChild(fragment);

      这里首先创建好片段中的元素节点,然后创建对应元素节点的属性和文本节点。最后由内之外的为对应元素添加子节点,逐步递推构成一个完整的DOM片段,最后将这一个片段添加到body体中。这样你所需的DOM片段就构建好了。至于这里用到了createDocumentFragment(),在后文中会详述它在性能优化中的作用。通过这个例子我们可以学会createElement(),setAttribute(),createTextNode(),appendChild()方法。

B :遍历文档节点

    这个例子使用了childNodes[]和递归方式来遍历整个文档,统计文档中出现的Element元素总数,并把Element标记名全部打印出来。需要特别注意的是,在使用DOM时,必须等文档被装载完毕再执行遍历等行为操作文档。

 1 var elementName="";//全局变量存储元素标签名称
 2 function countTotalElement(node){
 3     var total=0;
 4     if(node.nodeType==1){//检测是否是元素节点
 5             total++//计数器加1
 6             elementName=elementName+node.tagName+"\n";//保存标签名
 7             }
 8             var oChild=node.childNodes;//获取元素节点的子节点数组
 9             for(var i=0,l=oChild.length;i<l;i++){
10                 countTotalElement(oChild[i]);//递归每个子节点
11     }
12     return total;
13 }

     先就写这么多吧!文章太长容易让人烦躁。第二部分还要补充一下原生DOM方法扩展,DOM性能优化等内容。慢慢来吧,文中若有纰漏和错误还望指出。

posted on 2014-05-10 19:46 NET未来之路 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/3720917.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值