本章目录

 

什么是DOM

--概念

  • DOM: 就是Document Object Model。
  • 什么是Document?

    在JS里,Document指的就是像html,xml这样的标记语言文档。

  • 为什么要用标记语言?

    因为JS只能操作对象,而结构化的标记语言把它元素(比如<div>内容</div>)转成JS对象也比较方便,所以使用标记语言。

 

    JS在操作文档时,要把元素转换为对象。

  • 转成对象后能做什么?

    转成对象后就能够操作对象,改变标签属性,改变标签内容,改变标签样式。

 

 

DOM的使用

 DOM可以将页面元素转为JS对象,有两种方法转成对象:

--1.通过利用标签名,id,name方式来转换对象。(通过标签名一次转多个对象,id一次转1个对象,name一次转多个对象)具体使用下面方法:

  • var 对象名 = document.getElementsByTagName("标签名");
  • var 对象名 = document.getElementById("Id名");
  • var 对象名 = document.getElementsByName("元素名");

    可以将元素转换为对象,转了以后元素的属性将自动转为对象的属性

    转成对象后可以改变对象的属性,内容,进而改变元素的属性,内容。

注意:在转对象所用的标签,ID,元素名必须是在前面出现的,不然不能找到。

 

--使用元素属性,改变元素属性的方法

    转成对象后,元素的属性将自动转为对象的属性,可以直接引用,例如:

 
  1. <body>   
  2.     <a id="alink" href="www.baidu.com" target="_blank" title="this is a test!">test</a>  
  3. </body> 
  4. </html> 
  5. <script type="text/javascript"
  6.     var aobj = document.getElementById("alink"); //通过Id转为对象 
  7.     alert(aobj.title);    //通过对象属性引用元素属性 
  8.         aobj.title = "test finished!";  //通过对象属性改变元素属性 
  9.                           //此时元素的title属性已经成了"test finished!"             
  10. </script> 

     查看页面源代码:

    此时title属性的值已经是"test finished!"

    如果这个属性是本来没有的,那么会在原来元素中添加该属性

 

--改变元素(非表单元素)内容的方法

    利用对象属性(innerText,innerHTML,textContent),有两种方法可以改变元素的内容:

  • 1.只读取,改变文本,不能添加、读取HTML标签:innerText(ie使用),textContent(火狐使用)

    innerText的使用例子:

 
  1. <html> 
  2. <body>   
  3.     <a id="alink" href="www.baidu.com" target="_blank" title="this is a test!">test</a>   
  4. </body> 
  5. </html> 
  6. <script type="text/javascript"
  7.     var aobj = document.getElementById("alink"); 
  8.     aobj.innerText = "broTher";  
  9. </script> 

     在ie中,innerText可以改变元素的属性,如图:

 

    在火狐中,innerText不能改变元素的属性,如图:

    使用innerText,所有HTML标签将被视为文本,如下例:

 
  1. <body>   
  2.     <a id="alink" href="www.baidu.com" target="_blank" title="this is a test!">test</a>   
  3. </body> 
  4. </html> 
  5. <script type="text/javascript"
  6.     var aobj = document.getElementById("alink"); 
  7.     aobj.innerText = "<b>broTher</b>";  //在innerText的值中有<b>标签,但被视为文本 
  8. </script> 

     虽然innerText里面有<b>标签,<b>标签也被视为文本的一部分,如图:

 

  • 2.可以从内容中读取,在内容中添加HTML标签:innerHTML。

 内容中添加标签的例子:

 
  1. <body>   
  2.     <a id="alink" href="www.baidu.com" target="_blank" title="this is a test!">test</a>   
  3. </body> 
  4. </html> 
  5. <script type="text/javascript"
  6.     var aobj = document.getElementById("alink"); 
  7.     aobj.innerHTML = "<b>broTher</b>"//<b>将被浏览器作为标签    
  8. </script> 

    在浏览器中<b>将被解释为标签,如图:

 

 读取内容中的标签:

 
  1. <body>   
  2.     <a id="alink" href="www.baidu.com" target="_blank" title="this is a test!"><b>test</b></a>    
  3. </body> 
  4. </html> 
  5. <script type="text/javascript"
  6.     var aobj = document.getElementById("alink"); 
  7.     alert(aobj.innerHTML);   
  8. </script> 

可以读到<b></b>,如图:

 

 总结:简单的说,就是innerHTML可以往内容里读写带HTML标签的数据,innerText只能往内容里写文本数据。

由于innerText存在浏览器兼容问题,所以推荐使用innerHTML.

 

  • 读取整个元素的内容:outerText,outerHTML

 

--获取、改变表单value的方法

    利用对象属性(value),可以获取、改变表单的内容。

  • 获取表单的内容
 
  1. <input id="un" type="text" name="username" value="zhangsan"></ br> 
  2.         <script language = "javascript" type = "text/javascript"
  3.             var username = document.getElementById("un"); 
  4.             alert(username.value); 
  5. </script> 

    页面输出结果是:

 

 

  • 改变表单的内容
 
  1. <input id="un" type="text" name="username" value="zhangsan"></ br> 
  2.         <script language = "javascript" type = "text/javascript"
  3.             var username = document.getElementById("un"); 
  4.             username.value = "ddd"
  5.         </script> 

    页面输出结果是:

    表单的值已经成为ddd.

 

    还例如:

 
  1. <textarea id="un">dddd</textarea> 
  2.         <script language = "javascript" type = "text/javascript"
  3.             var username = document.getElementById("un"); 
  4.             alert(username.value); 
  5. </script> 

    执行结果如下:

 

--获取、改变元素的样式

  •  使用对象属性(style),可以获取和改变元素的样式。

    注意:对象名.style仍然是一个对象,在style里面有很多属性值可以设置。例如:

 
  1. aobj.style.backgroundColor = "red";//在css中背景颜色是background-color 
  2.                                  //在JS中"-"去掉,改成后面一个单词的首字母大写 
  3. aobj.style.fontSize = "3cm"

     在获取元素样式的时候,直接使用对象名.style只能获取内联样式(外部和嵌入样式都获取不了)。

     因此,获取宽度通常使用可视宽度属性 "对象名.style.offsetWidth"获取宽度。

  •  使用style属性只适合于改变单个样式,如果要改变多个样式,可以用className属性,给元素添加类,然后在css中写出该类的内容,就做到了给元素添加样式。

    例如:

 
  1. <style> 
  2.  .test { 
  3.    width:500px; 
  4.    height:600px; 
  5.    border:2px; 
  6.  } 
  7. </style> 
  8.  
  9. aobj.className = "test";//如果要加2个类test和demo,可以用aobj.className = "test demo"; 

 

 --2.通过数组获取对象

遍历document对象的方法:

 
  1. var pro=""
  2. for(pro in document) 
  3.     document.write("document."+pro+"="+document[pro]+"<br>"); 
 
  1. //下面是document对象中的一些是数组的属性。
  2. document.all=[object]   //html文档中所有元素 
  3. document.embeds=[object] //所有动画 
  4. document.scripts=[object] //所有脚本 
  5. document.applets=[ojbect] //所有java applet 
  6. document.p_w_picpaths=[object] //所有图片 
  7. document.forms=[object] //所有表单 
  8. document.anchors=[object] //所有锚点,所谓锚点就是带name的a标签 
  9. document.styleSheets=[object] //所有样式 
  10. document.links=[object] //所有链接 

 用数组获取对象示例:

 
  1. <form name="frm1"
  2.     <input type="text" name="username" value="zhangsan"></ br> 
  3. </form> 
  4. <form name="frm2"
  5.     <input type="text" name="username" value="lisi"></ br> 
  6. </form> 
  7. <form name="frm3"
  8.     <input type="text" name="username" value="admin"></ br> 
  9. </form> 
  10. <script>   
  11.     //访问元素属性的7种方法 
  12.     alert(document.forms[1].username.value);//通过索引数组 
  13.     alert(document.forms["frm2"].username.value);//通过关联数组,生成forms[]数组时同时生成了索引和关联成员
  14.     alert(document.forms.item(1).username.value);//通过item函数,对象数组都有item()方法
  15.     alert(document.forms.item("frm2").username.value);//通过item函数 
  16.     alert(document.forms.frm2.username.value);//通过对象成员的方式,JS中对象成员和数组方式可以互换 
  17.     alert(document.frm2.username.value);//通过对象成员frm2(因为是名字,所以可以不用写上级元素名) 
  18.     alert(document["frm2"].username.value);//通过关联数组 
  19.      
  20.      
  21. </script> 

说明:

    为什么alert(document.forms[1].username.value)中username又不是frm2的属性,怎么直接就成为了frm2的子对象?

  • 首先username是个元素的name,而在JS中如果元素有name,就可以直接把它的name当做对象名使用(虽然一般使用getElementsByname)。所以,username是个对象。
  • JS中子元素都是上级元素(可以是父,甚至可以是祖先元素)的子对象,所以username是frm2的子对象(下面的document.frm2也是同理,frm2是document的子对象)。

 

 Model的含义

     DOM的M表示Model,即模型,这个模型是将html文档看成一棵树,每个部分(元素,内容,属性,注释)都是一个node(节点),<html></html>是根node。

    只要知道一个节点,按关系找到其他节点。

     例如下面的html文档:

 
  1. <html>   
  2.         <head>   
  3.         </head>   
  4.         <body>   
  5.             <div>   
  6.                 wwww  
  7.             </div>   
  8.             <form>   
  9.                 <input>  
  10.                 <textarea></textarea>  
  11.                 <select>    
  12.             </form>   
  13.         </body>   
  14. </html>   

    转换成Model树后:

    父节点:parentNode

    子节点(第1个,最后1个):childNodes firstChild lastChild

    同胞节点(上一个,下一个):nextSibling previousSibling 

 

    每个节点都拥有包含着关于节点某些信息的属性,这些属性是:

  • nodeName 节点名称
  • nodeValue 节点值
  • nodeType 节点类型 

 

    nodeName属性含有节点的名称:

  • 元素节点的nodeName是标签名称
  • 属性节点的nodeName是属性名称
  • 文本节点的nodeName永远是#text
  • 文档节点的nodeName永远是#document

注释:nodeName所包含的XML元素的标签名称永远是大写的。

  • 对于文本节点,nodeValue属性包含文本。
  • 对于属性节点,nodeValue属性包含属性值。
  • nodeValue属性对于文档节点和元素节点是不可用的。

 

    nodeType属性可返回节点的类型:

      类型               类型号

  • 元素                1
  • 属性                2
  • 文本                3
  • 注释                8
  • 文档                9

 

文档流

    所谓Html文档流,就是一个Html页面被解析的过程,页面从上到下被解析完文档流就结束了。

    用document.write可以在文档流之中插入内容,但当文档流结束时,就无法在文档流中写入内容。比如在文档末尾添加:

 
  1. <a href="javascript:test()">add</a> 
  2. <javascript> 
  3.     function test(){ 
  4.         document.write("##############<br>"); 
  5.         document.write("##############<br>"); 
  6.     } 
  7. </javascript> 

    点击add后,不会在当前页面末尾加上2行################,而是会在新页面中输出2行##################。

 结论:

    不能以输出的方式在已经结束的文档流中添加内容。

 

--在文档流中创建节点

 
  1. document.createElement("元素名")   //创建元
  2. // 例如:aobj = document.createElement("h1"); 
  3. //函数返回创建的对象。

 

      

--在文档流中追加节点

  • 插入子节点

    可以使用appendChild()函数给文档流的某个节点的子节点列表的末尾添加新的子节点。格式如下:

 
  1. 要在哪个对象下追加.appendChild(被追加的对象) 

    比如在对象one下追加aobj对象,就是如下:

 
  1. <div id="one"> </div> 
  2. one = document.getElementById("one"); 
  3. one.appendChild(aobj);  //aobj也是获取的对象 

 

  • 插入兄弟节点

     可以使用insertBefore()函数在文档流的某个节点前插入节点。格式如下: 

 
  1. insertBefore(newchild,refchild) 
  2. //newchild     插入新的节点 
  3. //refchild      在此节点前插入新节点 

     例如:robj.insertBefore(newobj,robj);  //在robj前面插入节点newobj

 

 --从文档流中删除节点

  • 删除子节点
 
  1. nodeObject.removeChild(node) 
  2. //node    必需。指定需要删除的节点。 

    

注释:

Internet Explorer 会忽略节点间生成的空白文本节点(例如,换行符号),而 Mozilla 不会这样做。因此,在下面的例子中,我们会使用一个函数来检查最后一个子节点的节点类型。

 

 
  1. //check if last child node is an element node 
  2. function get_lastchild(n) 
  3. var x=n.lastChild; 
  4. while (x.nodeType!=1) 
  5.   { 
  6.   x=x.previousSibling; 
  7.   } 
  8. return x; 
  9.  
  10. xmlDoc=loadXMLDoc("books.xml"); 
  11. var x=xmlDoc.getElementsByTagName("book")[0]; 
  12.  
  13. deleted_node=x.removeChild(get_lastchild(x)); 
  14. document.write("Node removed: " + deleted_node.nodeName); 

       上面代码片段可删除首个 <book> 元素中的最后一个子节点。