1.DOM与DHTML概述:
dom(Document Object Model)三层模型:
dom1:将Html文档封装成对象
dom2,dom3:将Xml文档封装成对象
简单来说:将静态网页中的html标签(一经写好,固定了)"变活"(可操作)DHTML:dynamic html
DHMTL就是HTML+CSS+JS+DOM
html:负责将数据进行标签的封装
dom:负责将标签以及标签中的数据封装成对象
css:负责标签中数据的样式
JS:将三者进行融合,通过程序设计方式来操作这些对象
示意图:DOM树
加载进内存的是一颗DOM树.这些标签以及标签的数据都是这棵树上的节点.百度百科:
DOM的优势主要表现在:易用性强,使用DOM时,将把所有的XML/HTML文档信息都存于内存中,并且遍历简单.
DOM的缺点主要表现在:效率低,解析速度慢,内存占用量过高,对于大文件来说几乎不可能使用。另外效率低还表现在大量的消耗时间,因为使用DOM进行解析时,将为文档的每个element、attribute、processing-instrUCtion和comment都创建一个对象,这样在DOM机制中所运用的大量对象的创建和销毁无疑会影响其效率。
DOM树: (包含了标签,标签中的属性,标签中封装的数据)
2.DOM节点获取:
在上面的示意图中:
根节点:Document
如果父节点为:html
直接子节点:head,body
兄弟节点:head是body兄弟节点
a的下一个兄弟节点:h1,a没有上一个兄弟节点,属性是a节点对象的attributes集合的一员
h1的上一个兄弟节点:a<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title> DOM节点 </title> <style type="text/css"> #divID{background-color:red;} </style> <script type="text/javascript"> function demo(){ var divObj=document.getElementById("divID");//获取到第一个ID为divID的对象 //getNodeInfo(divObj);//name=DIV type=1 value=null(标签型节点为null) //1.获取div节点的父节点 getNodeInfo(divObj.parentNode);//name=BODY type=1 value=null //2.获取div节点的子节点 var childs=divObj.childNodes; //alert(childs.length); //getNodeInfo(childs[0]);//name=#text type=3 value=div标签中的内容 //3.获取div节点的上一个兄弟节点 //getNodeInfo(divObj.previousSibling);//name=#text type=3 value=空格(没有显示) //getNodeInfo(divObj.previousSibling.previousSibling);//name=INPUT type=1 value=null //4.获取div节点的下一个兄弟节点 //getNodeInfo(divObj.nextSibling.nextSibling);//name=TABLE type=1 value=null //5.通过遍历获取到A节点 /* var obj=divObj; while(((obj=obj.nextSibling).nodeName)!="A"); getNodeInfo(obj);//name=A type=1 value=null */ //6.获取节点td var tableObj=divObj.nextSibling.nextSibling; var tdObj; alert((tdObj=tableObj.getElementsByTagName("TD")).length);//4个td getNodeInfo(tdObj[0].childNodes[0]);//获取到单元格一的文本节点 //name=#text type=3 value=单元格一 //document的all集合 var allObj=document.all;//它将获取到所有文档中所有的对象(标签对象,注释comment) //除了TextNode对象 } function getNodeInfo(node){ alert("name="+node.nodeName+" type="+ node.nodeType+" value="+node.nodeValue);
/*也可以使用document.write*/
} </script> </head> <body> <input type="button" onclick="demo()" value="演示"/> <div id="divID">
div标签中的内容 <!--该ID与引用标签选择器的ID是一回事—>
</div> <table> <tr> <td id="divID">单元格一</td> <td>单元格二</td> </tr> <tr> <td>单元格三</td> <td>单元格四</td> </tr> </table> <a href="http://www.baidu.com">百度一下</a> </body>1. getNodeInfo(divObj.previousSibling);的打印结果是由于
<input type="button" onclick="demo()" value="演示"/>
<div id="divID">
之间有一个换行被浏览器解析为空白文本节点(也有的浏览器可能不解析该空白文本节点)即:name=#text type=3 value=空格(没有显示)<input type="button" onclick="demo()" value="演示"/><div id="divID">
以上写法获取到的上一个兄弟节点是input2.document对象中的方法:
a.getElementById:通过ID属性值获取对应的节点对象.如果有多个标签的id值相同,获取到第一个id所属对象,尽量保证id唯一性
b.getElementsByName 根据标签的 NAME属性 值获取对象,返回对象数组(集合):例如:同一组radio的name值相同
c.getElementsByTagName:既没有id,也没有name时,可以通过标签名来获取节点对象,返回是对象集合(数组).注意:document中的该方法将作用于整个文档.3.节点类型:
标签型节点的type为1(nodeType属性)
属性节点:类型:2
文本性节点:类型:3
注释型节点:类型:8
document:类型:9父节点 parentNode
直接子节点 childNodes(返回一个对象数组)
兄弟节点
上一个兄弟节点 previousSibling
下一个兄弟节点 nextSibling
一个父节点可能有多个直接子节点,但是一个直接子节点只有一个父节点.
3.将文档中的节点以层级方式输出:
listNodes.js:
/*JavaScript*/ /*递归遍历*/ function listNodes(node,level){ printNodes(node,level); var childs=node.childNodes; ++level; for(var index=0;index<childs.length;++index) if(childs[index].hasChildNodes()) listNodes(childs[index],level); else printNodes(childs[index],level); } var str=""; /*为了凸显层级关系*/ function nodeLevels(level){ var blankStr=""; for(var i=0;i<level;++i) blankStr+=" "; blankStr+="|--"; return blankStr; } function printNodes(node,level){ str += nodeLevels(level)+node.nodeName+ "..."+node.nodeType+"..."+node.nodeValue+" "+"<br/>"; } function getDocumentNodes(){ listNodes(document,0); document.write(str); }第二种方法:
var str=""; var newWindow=window.open("","_blank"); function printNodes(node,level){ str = nodeLevels(level)+node.nodeName+ "..."+node.nodeType+"..."+node.nodeValue+" "+"<br/>"; newWindow.document.write(str); } function getDocumentNodes(){ listNodes(document,0); //document.write(str);//正常输出,输出的是最终的字符串 } /* 不在新的窗口中写入会引发类似下面问题: 顺序遍历1,2,3 遍历1->页面又写入1->2,3,1 遍历2->页面又写入2->3,1,2 遍历3->页面又写入3->1,2,3 ..... 死循环 */<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>列出文档中所有节点的层级</title> <script type="text/javascript" src="ListNodes.js"></script> <script type="text/javascript"> alert(document.getElementsByTagName("BODY").length);//0 //此时浏览器还未加载body标签 // getDocumentNodes(); </script> </head> <body> <!--测试注释--> <script type="text/javascript"> alert(document.getElementsByTagName("BODY").length);//1 getDocumentNodes(); </script> </body> </html>写在<head></head>中的脚本注意alert(document.getElementsByTagName("BODY").length);会在加载body前执行,由于body还未加载因此获取不到.
一般将JS语句封装到函数中,那么只有在调用该函数才会执行,例如:onclick=”click()” 在事件源上注册事件,虽然JS中的click函数定义在<head></head>中,但是没调用,不执行,直到鼠标左键被按下->事件被激发,才会调用click方法去处理.当你去点击鼠标时->此时页面已加载完毕.
关于HTML页面加载可以参考:
http://blog.csdn.net/sun93732/article/details/5898605