DOM技术
Posted MiroKlose
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DOM技术相关的知识,希望对你有一定的参考价值。
DOM概述
DOM:Document Object Model(文档对象模型)(DOM核心就是 文档变对象,标签也变对象,属性也变对象,反正就是把标记文档拆散)
用来将标记型对象封装成对象,并将标记型文档中的所有内容(标签,文本,属性)都封装成对象。
封装成对象的目的是为了方便操作这些文档和文档中的内容,方便动态(增删改查)。
文档:标记型文档
对象:封装了属性和行为的实例
模型:所有标记型文档都具备的一些共性特征的一个体现
只要是标记型文档,DOM技术都可以进行操作。
常见的标记型文档:html xml
DOM这种技术如何对标记型文档进行操作的?
首先对标记型文档进行解析。
DOM解析方式
将标记型文档解析成一个DOM树,并将树中的内容封装成节点对象
在浏览器中,DOM解析将按照标签的层次关系体现出标签的所属,形成一个树状结构,称为DOM树。
DOM解析由浏览器自动完成,解析之后,生成一个document对象,并将它加载进内存。
比如下面这个html文档和相应的DOM树,整个HTML文档被封装成一个document对象。
<html> <head> <title>这是演示文档</title> </head> <body> <div>div区域</div> <dl> <dt>上层项目</dt> <dd>下层项目</dd> </dl> <table> <tbody> <tr> <th>表头</th> <td>单元格</td> </tr> </tbody> </table> <form> <input type="text"/> </form> </body> </html>
DOM树:
树中的标签,文本,和属性称为节点,也称为对象。标签也称为页面中的元素。乱
理解:html标签是静态的,全是死的,没有办法对其中的某个标签进行操作的,现在通过DOM技术把标签,文本,属性全部单个拿出来,那么文档就可以对每个元素进行操作
DOM技术把文档文档中的元素全变成对象,这样才能挨个的动态操作。
DOM解析方式的好处:可以对树中的节点进行任意操作,比如:增删改查。
弊端:这种解析方式需要将真个标记型文档加载进内存,意味着如果标记型文档的体积很大,浪费较大内存空间。
SAX解析方式
是由一些组织定义的民间常用的解析方式,并不是w3c标准,而DOM是w3c的标准。
SAX解析方式:是基于事件驱动的解析。
这种解析方式,并不将整个文档一次性读取,按照每一个标签进行解析,读到一个标签的开头,相当于处罚一个事件,然后对标签内容进行解析,然后读取到结束标签,这个解析就完成了。
这种解析方式获取数据速度很快(查),但是不能对标记进行增删改的动作。根据需求来灵活选择。
DOM的三级模型
DOM level 1:将html文档封装成对象。
DOM level 2:在level 1 基础上加入新功能,比如解析名称空间(html标签中的xmln属性代表命名空间,这个名字必须唯一,一般用网站的域名来作为命名空间,)
DOM level 3:将xml文档封装成对象。
这三种就完成了对常见的标记文档的解析
DOM是一种底层的技术,各个语言都对外提供了DOM的解析工具,java中的dom4j,jaxp(java内置)
同样javascript也有相应的解析工具,在前端中,用Javascript进行解析。
DHTML概述
动态的HTML,不是一门语言,是多项技术综合体的简称
html+css只是一个静态页面,加入Javascript和DOM之后,就动起来了。
这四个技术在动态html页面效果定义时,都属于什么角色呢,负责什么职责呢?
HTML:负责提供标签,对数据进行封装,目的是便于对该标签中的数据进行操作。(用标签封装数据)
CSS:负责提供样式属性,对标签中的数据进行样式的定义。(对数据进行样式定义)
DOM:负责将标记型文档以及文档中的所有内容进行解析,并封装成对象,在对象中定义了更多的属性和行为,便于对对象操作。
Javascript:负责提供程序设计语言,对页面中的对象进行逻辑操作。比如想添加十个节点,就用循环,不然要挨个添加,甚是麻烦!(负责页面行为,就是页面动态效果)
综上所述:Javascript是动态效果的主力编程语言。
DHTML+XMLhttpRequest = AJAX
BOM模型
Browser Object Model(浏览器对象模型)
DOM为了方便操作文档,BOM为了方便操作浏览器。
bom中有一些对象,这些对象可以直接在javascript代码中使用,用来获取相应的信息。
window对象
浏览器对应的对象就是window对象
注意:只要打开浏览器,window对象就在内存中,可以在javascript中直接使用,其实由于window对象是默认存在的,所以window对象可以缺省
appName,history,navigator等属性。
一些常用方法:
alert();弹窗
confirm();弹出一个是否选择窗口,根据不同的选择,该函数返回是或否,通过对该返回值的判定,进而选择执行不同的操作。(if操作)
focus();获取焦点。
setTimeout(js语句,毫秒值);超过毫秒值就执行js语句。类似于单片机的中断?函数返回一个整数,用来区分多个计时,将该值放到clearTimeout中可以取消该计时
setInterval(js语句,毫秒值);每隔毫秒值执行一次。函数返回一个整数,用来区分多个计时,将该值放到clearInterval中可以取消该计时
clearTimeout();
clearInterval();
moveBy(横坐标偏移量,纵坐标偏移量);当前浏览器窗口按照偏移量移动。
moveTo(横坐标,纵坐标);直接移动到指定坐标点。
open("网址","打开方式","height=100,width=100,status=yes,toolbar=yes,menubar=yes,location=yes");打开方式:新窗口(_blank),有状态栏,有工具栏,有菜单栏,有地址栏
close();关闭窗口,必须是自己通过代码新打开的窗口才能通过close来关闭。
常见事件:
直接指向一个函数即可,事件触发时,就会执行函数。
onload=function(){
code...
}
onload:当窗口中的所有动作完成后,立刻触发,网页内容加载完后执行。
unbeforeunload:点击关闭浏览器窗口,关闭之前会执行。
onunload:点击关闭浏览器窗口,浏览器关闭之后调用。
属性:
status:属性中的值就会显示在状态栏。
弹窗广告:
location对象
和java中的url对象类似,location中的属性可以获取,也可以赋值,相当于一个变量。
location.protocol:获取地址栏中的协议
location.href:可以对该变量赋值,这会改变地址栏的值并进行解析,如果解析是http协议,就会对链接进行访问。
location.pathname:路径名
DOM操作
节点的获取
通过document直接获取节点
通过document对象来操作标记文档,该对象将标记型文档中的各个节点对象进行了封装,通过document就可以获得各个节点。
用document对象中获取节点的方法:
1,getElementById();通过标签的ID来获取节点,返回该标签节点。
2,getElementsByName();//通过标签的name属性获取节点,因为name属性会重名,返回的是一个数组,注意,不是所有标签都具有name属性。
3,getElementsByTagName();//通过标签名来获取节点,同样的,标签名也会出现重复,返回值也是一个数组。
常见的节点有三种:1,标签型节点 节点类型:1
2,属性节点 节点类型:2
3,文本节点 节点类型:3
其中,标签型节点没有值,属性节点和文本节点是有值的。
节点的必备属性
节点是Object类型的,每个节点都有三个必备属性:
1,节点名称(DIV,INPUT等)
.nodeName
2,节点类型
.nodeType
3,节点值
.nodeValue
不同的节点还有其各自特殊的属性
例如:
div标签节点中的其他属性和方法:
.innerHTML div节点中的文本,可以用来获取区域的文本,对其赋值也可以改变div中的文本。
.getElementsByTagName();获取div标签下一级的节点,用来获取内部节点。由于div标签是容器型的标签,所以会有这个方法,但是并没有 getElementsByName()和getElementById()这两个方法,因为并不能保证每个内部标签都有name属性或者ID。
input标签节点中的其他属性:
.type
.name
.value 获取用户输入的内容,可以用来在客户端进行输入的校验,这个要与必备属性的nodeValue区分,由于是标签型节点,所以点没有值。
a节点中的属性和方法:
.innerHTML:获取超链接内容。
.target:target属性可设置或返回在何处打开表单中的 action-URL。
.eg:
<input type="button" value="演示document获取节点" onclick="Demo()" /> <script type="text/javascript"> function Demo(){ //获取页面中的div节点,用第一个方法 var divNode = document.getElementById("divid"); alert(divNode.nodeName+":"+divNode.nodeType+":"+divNode.nodeValue); var text = divNode.innerHTML; alert(text); divNode.innerHTML = "div文本区域被改变".fontcolor("red");//这样就可以改变字符串的颜色,记住 //获取文本框节点,用第二个方法 var nodes = document.getElementsByName("user");//返回的是一个数组 //或者可以直接获取这个数组的第一个元素 var userNode = document.getElementsByName("user")[0];//这是单独的一个元素 alert("length:"+nodes.length); alert("nodeName:"+nodes[0].nodeName); alert("nodeValue:"+nodes[0].nodeValue); alert("nodeType:"+nodes[0].nodeType); alert("type:"+nodes[0].type); alert("name:"+nodes[0].name); alert("value:"+nodes[0].value);
//通过标签名获取节点
var nodes = document.getElementsByTagName("a");
alert(nodes.length);
alert(nodes[0].innerHTML);
alert(nodes[0].href);
nodes[0].target = "_blank";
//获取内部节点
var divNode = document.getElementById("divId1");
var aNodes = divNode.getElementsByTagName("a");//返回数组
aNodes[0].target = "_blank";
alert(aNodes[0].innerHTML);
} </script> <div id = divid>这是一个div区域</div> <input type="text" name="user"/>
<a href="www.baidu.com">百度首页</a> <!--通过标签 tagname 获取该标签节点-->
<div id="divId1">
<a href="www.hao123.com">百度门户</a>
</div>
通过节点层次关系获取节点
直接获取的方法有弊端,并不是所有的节点都有ID或者name属性,这样获取节点麻烦。
节点之间的关系:父节点,子节点,兄弟节点,兄弟节点之间分上一个节点,下一个节点。
任何一个节点都有一些属性
.parentNode:由于父节点只有一个,所以属性就可以,对应一个节点对象
.childNodes:返回直接后代的一个集合,对应一个节点集合
.previousSibling:上一个兄弟节点,同样对应一个节点对象
.nextSibling:下一个兄弟节点,对应一个节点对象
TIPS:兄弟节点尽量少用,因为在不同的浏览器解析兄弟节点不一致,会导致兼容性问题,谷歌浏览器中,DOM的解析方式和IE不同,谷歌浏览器会把回车符解析为一个文本节点(#text),而IE浏览器会跳过空格,直接解析下一个节点,例如下面程序中的获子节点部分。
<html> <head> <title>这是演示文档</title> </head> <body> <input type="button" value="演示document获取节点" onclick="Demo()" /> <script type="text/javascript"> function Demo(){ var tabNode = document.getElementById("tabId"); //获取父节点 var parNode = tabNode.parentNode; alert("父节点:"+parNode.nodeName);//BODY //获取子节点 var chiNodes = tabNode.childNodes;//注意:表格的下一级标签默认是TBODY,就算不写,也会存在 alert("子节点:"+chiNodes[0].nodeName);//TBODY 在IE中显示TBODY 在谷歌浏览器中显示#text表示文本节点 alert("再下一节点:"+chiNodes[0].childNodes[0].nodeName);//按照层次结构点下去 //获取兄弟节点 var broNode = tabNode.previousSibling;//获取上一个兄弟节点,下一个类似 alert("上一个兄弟节点;"+broNode.nodeName); } </script> <div>div区域</div> <dl> <dt>上层项目</dt> <dd>下层项目</dd> </dl> <table id="tabId"> <tbody> <tr> <th>表头</th> <td>单元格</td> </tr> </tbody> </table> <form> <input type="text"/> </form> </body> </html>
节点的操作
操作无非增删改查,查上面已经解决了,现在解决增删改。
增
向div标签中添加文本
1,创建节点,利用的是document中的方法
var oTextNode = document.creatTextNode();创建一个文本节点。
2,获取div节点
var oDivNode = document.getElementById("div_1");div的ID是div_1
3,添加节点
var oDivNode.appendChild(oTextNode);向div节点oDivNode中添加文本节点。
向div标签中添加按钮节点
1,创建按钮节点
var oButtonNode = document.createElement("input");创建一个 imput 元素
oButtonNode.type = "button";设置节点的类型为按钮
oButtonNode.value = "自定义添加的按钮";设置按钮的文本
2,添加按钮节点
oDivNode.appendChild(oButtonNode);向div节点oDivNode中添加按钮节点
另外一种简单方法:
利用容器型标签的 innerHTML 属性来完成,这个非常强,innerHTML中的文本会按照html来解析
oDivNode.innerHTML = "犯我强汉,虽远必诛。" ;
oDivNode.innerHTML = "<input type=\'button\' value=自定义按钮>" ;注意字符串中的双引号要用单引号代替
oDivNode.innerHTML = "<a href=\'www.baidu.com\'>超链接</a>" ;
删
1,获取想要删除的节点
var oDivNode_1 = document.getElementById("div_1");div的ID是div_1
2,删除节点,要被删除的节点自己调用方法(这种方法较少使用,推荐使用下一个,这句代码在谷歌浏览器运行不了,ie可以。)
oRemoved = oDivNode_1 .removeNode(false);false代表只删除该div节点,true代表删除该节点和该节点下面的所有子节点,默认为false,返回值是被删 除的节点对象
2,一般使用removeChild()方法,这个方法是删除子节点,所以要先获取 要被删除的节点的父节点,然后用removeChild()方法删除节点本身。(通用)
oDivNode_1.parentNode.removeChild(oDivNode_1);父节点来删除自己
改(替换和克隆节点)
替换就是移动
1,获取两个节点,用div_3替换div_1
var oDivNode_1 = document.getElementById("div_1");div的ID是div_1div_1
var oDivNode_3 = document.getElementById("div_3");
2,替换
oDivNode_3.replaceNode(oDivNode_3);不建议使用,谷歌不支持
oDivNode_1.parentNode.replaceChild(oDivNode_3,oDivNode_1);用3替换1,新在前,旧在后,建议使用,通用的
克隆就是复制
用div_3替换div_1,并保留div_3
1,获取两个节点,并创建一个要保留节点的副本。
var oDivNode_1 = document.getElementById("div_1");div的ID是div_1div_1
var oDivNode_3 = document.getElementById("div_3");
var oCopyDivNode_3 = oDivNode_3.clone(false);创建副本,false代表只复制div区域,div区域下面的节点不复制,true则表示全部复制
2,用克隆出来的副本去替换div_1,仍然是用获取父节点来操作
oDivNode_1.parentNode.replaceChild(oCopyDivNode_3 ,oDivNode_1);
<html> <head> <title>这是演示文档</title> <style type="text/css"> div{ border:blue 1px solid ; width:300px; height:50px; padding:20px; margin:10px; } #div_1{ background-color:#00ccff; } #div_2{ background-color:#0199ff; } #div_3{ background-color:#0211ff; } #div_4{ background-color:#0366ff; } </style> </head> <body> <input type="button" value="创建并添加节点" onclick="crtAndAddNode()"/> <input type="button" value="删除节点" onclick="deleteNode()"/> <input type="button" value="修改节点" onclick="changeNode()"/> <script type="text/javascript"> function crtAndAddNode(){ //1,创建文本节点 var otextNode = document.createTextNode("秦时明月汉时关,万里长征人未还。"); //2,获取div_1节点 var oDivNode_1 = document.getElementById("div_1"); //3,将文本节点添加到div_1节点 oDivNode_1.appendChild(otextNode); //1,创建一个按钮节点 var oButtonNode = document.createElement("input"); oButtonNode.type = "button"; oButtonNode.value = "自定义添加的按钮"; //2,将按钮节点添加到div_1节点 oDivNode_1.appendChild(oButtonNode); //利用innerHTML,字符串中的内容会按照html来解析 var oDivNode_2 = document.getElementById("div_2"); var oDivNode_3 = document.getElementById("div_3"); var oDivNode_4 = document.getElementById("div_4"); oDivNode_2.innerHTML = "犯我强汉,虽远必诛。" ; oDivNode_3.innerHTML = "<input type=\'button\' value=自定义按钮>" ; oDivNode_4.innerHTML = "<a href=\'www.baidu.com\'>超链接</a>" ; } function deleteNode(){ //获取div_1节点 var oDivNode_1 = document.getElementById("div_1"); //删除节点(较少使用) //var oRemoved = oDivNode_1.removeNode(true); //获取div_2节点 var oDivNode_2 = document.getElementById("div_2"); //获取父节点来删除节点本身 oDivNode_2.parentNode.removeChild(oDivNode_2); } function changeNode(){ //用div_3节点来替换div_1节点 var oDivNode_1 = document.getElementById("div_1"); var oDivNode_3 = document.getElementById("div_3"); //不建议使用 //oDivNode_1.replaceNode(oDivNode_3); //建议使用replaceChild() oDivNode_1.parentNode.replaceChild(oDivNode_3,oDivNode_1); } </script> <div id="div_1"> </div> <div id="div_2"> 但使龙城飞将在,不教胡马度阴山。 </div> <div id="div_3"> 骝马新跨白玉鞍,战罢沙场月色寒。 </div> <div id="div_4"> 城头铁鼓声犹振,匣里金刀血未干。 </div> </body> </html>
常见的网页效果示例
代码所处位置:
CSS:CSS代码封装在<style></style>标签中,并将其放在<head></head>中,这部分内容会先加载到内存中,增加运行速度。
javascript:javascript代码封装在<script type="text/javascript"></script>中,一般放在需要访问的位置周围即可。如果脚本要处理整个页面,那也放在<head>标签中。
新闻字体
改变新闻字体的大中小
方法一:直接在javascript代码中设置节点的属性
以上是关于DOM技术的主要内容,如果未能解决你的问题,请参考以下文章