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代码中设置节点的属性