由于DOM(文档对象模型)概念的推出,这个API使HTML如虎添翼,但是有些学DHTML的朋友还是有些困挠,只是因为目前的手册的书写不太科学,是 按字母来分的,不便查阅.其实DOM中最关键是要掌握节点与节点之间的关系(between node and node),想学习DHTML中的DOM 千万不要从头到尾地看遍所有的属性和方法,你有三国时张松的"过目不忘"的本领吗?没有吧,那就听我分析一下:
其实DOM教给我们的就是一个层次结构,你可以理解为一个树形结构,就像我们的目录一样,一个根目录,根目录下有子目录,子目录下还有子目录…… 根节点: DOM把层次中的每一个对象都称之为节点(NODE),以HTML超文本标记语言为例:整个文档的一个根就是<html>,在DOM中可以使用document.documentElement来访问它,它就是整个节点树的根节点(ROOT) 子节点: 一般意义上的节点,根节点以下最大子节点就是主文档区<body>了,要访问到body标签,在脚本中应该写: document.body body区以内所有的文本及HTML标签都是文档的节点,分别称为文本节点、元素节点(或者叫标签节点),大家知道HTML说到底只是文本而矣,不论怎么样的网页必然由这两个节点组成,也只能由这两个节点组成 节点之间的关系: 节点之间的关系也是DOM中最重要的一个关节,如何正确地引用到节点对象,一定要清楚节点树各个节点的相互描述方式,在DHTML里,Javascript脚本就用了各个节点对象的一整套方法和属性去描述另外的节点对象。 节点的绝对引用: document.documentElement 返回文档的根节点 ----------------------------------------------------------------------------- document.activeElement 返回当前文档中被击活的标签节点 ----------------------------------------------------------------------------- event.fromElement 返回鼠标移出的源节点 ----------------------------------------------------------------------------- event.toElement 返回鼠标移入的源节点 ----------------------------------------------------------------------------- event.srcElement 返回激活事件的源节点 节点的相对引用:(设当前对节点为node) node.parentElement node.parentNode 返回父节点 ------------------------------------------------------------------------------ node.childNodes 返回子节点集合(包含文本节点及标签节点) ----------------------------------------------------------------------------- node.children 返回子标签节点集合 ---------------------------------------------------------------------------- node.textNodes 返回子文本节点集合 ------------------------------------------------------------ node.firstChild 返回第一个子节点 ------------------------------------------------------------- node.lastChild 返回最后一个子节点 -------------------------------------------------------------- node.nextSibling 返回同属下一个节点 -------------------------------------------------------------- node.previousSibling 返回同属上一个节点 节点的各种操作:(设当前的节点为node) 新增标签节点句柄: document.createElement(sNode) //参数为要新添的节点标签名,例:newnode=document.createElement("div"); 1、添加节点: 追加子节点: node.appendChild(oNode) //oNode为生新增的节点句柄,例:node.appendChild(newnode) 应用标签节点 node.applyElment(oNode,sWhere)//oNode为生新增的节点句柄,sWhere有两个值:outside / inside,加在当前节点外面还是里面 插入节点 inode.insertBefore() node.insertAdjacentElement() node.replaceAdjacentText() 2、修改节点: 删除节点 node.remove() node.removeChild() node.removeNode() 替换节点 node.replaceChild() node.replaceNode() node.swapNode() 3、复制节点: 返回复制节点引用 node.cloneNode(bAll)//bAll为布尔值,true / false 是否克隆该节点所有子节点 4、节点信息 是否包含某节点 node.contains() 是否有子节点 node.hasChildNodes() 首先需要理解的一点是,DOM是针对XML的基于树的API,它的实现有很多(各语言基本都有自己的实现),我们讨论的是javascript中或者说xhtml(html)对DOM的实现。
一、使用DOM 考虑一个html文件: <html>
<head><title>测试</title></head> <body> <p>测试</p> </body> </html> 1.访问节点: 访问html元素:var oHtml=document.documentElement; 获取head元素:var oHead=oHtml.firstChild; 获取body元素:var oBody=oHtml.lastChild; 或者 var oBody=document.body; 也可以通过childNodes来做同样的工作: var oHead=oHtml.childNodes[0] 或者 oHtml.childNodes.item(0); var oBody=oHtml.childNodes[1] 或者 oHtml.childNodes.item(1); 判断节点间关系: alert(oHead.parentNode==oHtml);
alert(oBody.previousSibling==oHead); alert(oHead.nextSibling==oBody); alert(oHead.ownerDocument==document); 2.检测节点类型: 通过节点的nodeType属性来检验节点类型: alert(document.nodeType); //输出9 需要注意的是,DOM兼容的浏览器(以FF2.0为例),拥有Node.DOCUMENT_NODE、Node.ELEMENT_NODE等常量。各常量名称与数值对照表如下: ELEMENT_NODE 1
ATTRIBUTE_NODE 2 TEXT_NODE 3 CDATA_SECTION_NODE 4 ENTITY_REFERENCE_NODE 5 ENTITY_NODE 6 PROCESSING_INSTRCTION_NODE 7 COMMENT_NODE 8 DOCUMENT_NODE 9 DOCUMENT_TYPE_NODE 10 DOCUMENT_FRAGMENT_NODE 11 NOTATION_NODE 12 IE6不支持,不过你可以自定义一个JS对象Node。 3.处理特性 处理特性可以使用标准的NameNodeMap中的方法: getNamedItem(name) removeNamedItem(name) setNamedItem(node) item(pos) 比如:<p id="test">测试</p> 假设变量oP是上面的p节点的引用,我们要访问oP的id属性: var sId=oP.attributes.getNamedItem("id").nodeValue; 这些方法用起来很累赘,所以DOM又定义了三个方法来简化: getAttribute(name) ——返回名称为name的属性的值 setAttribute(name,value) ——顾名思义 removeAttribute(name) ——顾名思义 上面的例子可以改写为: var sId=oP.getAttribute("name"); 4.访问指定节点: 熟知的getElementByTagName(name),getElementByName(name),getElementById(id)三个方法,不再展开。 5.创建和操作节点: (1)创建新节点,一张IE(6.0)和FF对DOM Level1的创建新节点方法支持的对照表: 方法 IE FF
createAttribute(name) Y Y createCDATASection(text) N Y createComment(text) Y Y createDocumentFragment() Y Y createElement(tagName) Y Y createEntityReference(name) N Y createProcessingInstruction( target,data) N Y createTextNode(text) Y Y 下面介绍常用的几个方法 (2)createElement(),createTextNode(),appendChild() 例子: <html>
<head> <title>createElement() Example</title> <script type="text/javascript"> function createMessage() { var oP = document.createElement("p"); var oText = document.createTextNode("Hello World!"); oP.appendChild(oText); document.body.appendChild(oP); } </script> </head> <body onload="createMessage()"> </body> </html> 在页面载入后,创建节点oP,并创建一个文本节点oText,oText通过appendChild方法附加在oP节点上,为了实际显示出来,将oP节点通过appendChild方法附加在body节点上。此例子将显示Hello World! (3)removeChild(),replaceChild()和insertBefore() 从方法名称就知道是干什么的:删除节点,替换节点,插入节点。需要注意的是replaceChild和insertBefore两个参数都是新节点在前,旧节点在后。 (4)createDocumentFragment() 此方法主要是为了解决大量添加节点时,速度过慢。通过创建一个文档碎片节点,将要添加的新节点附加在此碎片节点上,然后再将文档碎片节点append到body上面,替代多次append到body节点。 例子: <html>
<head> <title>insertBefore() Example</title> <script type="text/javascript"> function addMessages() { var arrText = ["first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth", "tenth"]; var oFragment = document.createDocumentFragment(); for (var i=0; i < arrText.length; i++) { var oP = document.createElement("p"); var oText = document.createTextNode(arrText[i]); oP.appendChild(oText); oFragment.appendChild(oP); } document.body.appendChild(oFragment); } </script> </head> <body onload="addMessages()"> </body> </html> 二、HTML DOM的特征功能 HTML DOM的特性和方法不是标准的DOM实现,是专门针对HTML同时也让一些DOM操作变的更加简便。 1.让特性像属性一样 访问某元素的特性需要用到getAttribute(name)方法,HTML DOM扩展,可以直接使用同样名称的属性来获取和设置这些值: 比如 <img src="test.jpg"/> 假设oImg是此元素的引用 (oImg.getAttribute("src")可以直接写成:oImg.src,设置值简化为: oImg.src="test2.gif"; 唯一特殊的class属性,因为class是ECMAScript的保留字,所以替代的属性名是className. 2.table的系列方法: 为了简化创建表格,HTML DOM提供了一系列的表格方法,常用几个: cells ——返回</tr>元素中的所有单元格 rows ——表格中所有行的集合 insertRow(position) ——在rows集合中指定位置插入新行 deleteRow(position) ——与insertRow相反 insertCell(position) ——在cells集合的指定位置插入一个新的单元格 deleteCell(position) ——与insertCell相反 三。遍历DOM DOM的遍历是DOM Level2中提出的标准,IE6没有实现,Mozilla和Safari已经实现,最新IE7不清楚是否实现。不再展开,具体请见《JavaScript高级程序设计》 |