轻松学习JavaScript二十一:DOM编程学习之获取元素节点的子节点和属性节点
我们这里所说的获取元素节点的全部子节点包括元素子节点和文本节点两种。
还是拿上一篇博文的代码实例进行
分析:
<span style="font-size:18px;"><span style="font-size:18px;"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>JS代码位置</title> <script type="text/javascript"> window.onload=function(){ } </script> </head> <body> <p>你喜欢那个城市</p> <ul id="city"> <li id="bj" class="BJ" name="Beijing" style="color:red">北京市</li> <li>天津市</li> <li>上海市</li> <li>重庆市</li> </ul> <p>你喜欢那个游戏</p> <ul id="game"> <li id="hsjj">红色警戒</li> <li>天龙八部</li> <li>罪恶都市</li> <li>反恐精英</li> </ul> <p>选择性别:</p> <input type="radio" name="sex" value="male" />男 <input type="radio" name="sex" value="female" />女 </body> </html></span></span>
因为节点能够分为元素节点,属性节点和文本节点。而这些节点又有三个很实用的属性,nodeName属性和
nodeType属性是仅仅读,而nodeValue属性是能够读写的:
<span style="font-size:18px;"><span style="font-size:18px;">//获取id="city"的元素节点 var cityNode=document.getElementById("city"); alert(cityNode.innerHTML);//获取当前元素节点里的内容。包括标签与文本 alert(cityNode.tagName);//返回:UL alert(cityNode.nodeName);//返回:UL,与tagName等价 alert(cityNode.nodeType);//返回:1表示元素节点 alert(cityNode.nodeValue);//返回:null(注意和innerHTML的差别)</span></span>使用innerHTML属性返回到的内容为:
节点的层次结构能够划分为:父节点与子节点。兄弟节点两种类型结构。当我们获取当中一个元素节点的时候,
就能够使用层次节点属性来获取与它相关层次的节点。而层次节点的属性有:
(1)childNodes属性
childNodes数属性能够获取某一个元素节点的全部字节点,这些字节点包含元素字节点和文本子节点。它返回的
也是一个字节点对象数组。我们使用childNodes[n]返回子节点对象。同一时候我们能够使用节点属性中的nodeValue属性
对其文本节点进行赋值。
在这里我们要注意:
1)获取的文本子节点无法使用innerHTML这个属性输出文本内容,由于这个是非W3C标准的属性必须在获取元素
节点的时候,才干输出里面包括的文本,然而元素节点能够使用innerHTML属性和nodeValue属性。
2)当我们操作元素节点赋值时,nodeValue属性会把包括在文本里的HTML转义成特殊字符,从而达到单纯文本的
效果,而innerHTML属性去能够解析HTML,输出解析后的HTML文档。
实例一:
<span style="font-size:18px;"><span style="font-size:18px;">//获取id="city"的元素节点 var cityNode=document.getElementById("city"); //获取cityNode元素节点的子节点 var liNodes=cityNode.childNodes; alert(liNodes);//返回:object nodeList表示节点对象数组 alert(liNodes.length);//返回:9,这里包括了4个元素节点和5个空文本节点(ul标签内的空白部分),针对非IE浏览器。IE是4个</span></span>
从得出的结果看出这个得到元素节点的全部字节点并非如我们所愿,我们仅仅想得到那4个li元素子节点,在IE浏
览器是自己主动回避空白文本节点的,这是我们所想要的结果。
因此又回到了利用getElemntsBytagName()方法来获取这4
个元素字节点数组:
<span style="font-size:18px;"><span style="font-size:18px;">//获取id="city"的元素节点 var cityNode=document.getElementById("city"); //获取id="city"的元素节点中的全部元素名为li的元素子节点 var liNodes=cityNode.getElementsByTagName("li");</span></span>
补充:另一个非W3C标准的children属性,这个属性是仅仅得到有效子节点。即忽略空文本节点:
<span style="font-size:18px;"><span style="font-size:18px;">//获取id="city"的元素节点 var cityNode=document.getElementById("city"); //获取元素节点的全部子节点 var liNodes=cityNode.children; alert(liNodes);//返回:object HTMLCollection alert(liNodes.length);//返回:4也就是4个li子元素节点 alert(liNodes[0].nodeName);//返回:LI</span></span>
那么我们从上面实例一(没有忽略空白文本节点的)得到的字节点数组再进行节点属性操作。我们知道第一个li元素
子节点是全部字节点的第二个,第一个是空白文本节点,以下的实例是以非IE浏览器进行的測试,IE浏览器的结果就
不再进行描写叙述。
因此看以下的操作:
<span style="font-size:18px;"><span style="font-size:18px;">alert(liNodes[0]);//返回:object Text表示文本节点对象 alert(liNodes[0].nodeName);//返回:#Text alert(liNodes[0].nodeType);//返回:3表示文本节点 alert(liNodes[0].nodeValue);//返回:空 liNodes.nodeValue="測试";//在HTML文档中会输出:測试</span></span>得到的子节点对象数组中的第二个是子元素节点:
<span style="font-size:18px;"><span style="font-size:18px;">alert(liNodes[1]);//返回:object HTMLLIElement表示元素节点对象 alert(liNodes[1].nodeName);//返回:LI alert(liNodes[1].nodeType);//返回:1表示元素节点 alert(liNodes[1].nodeValue);//返回:null</span></span>
从上面操作的情况来看这样的获取全部字节点的方法并不有用,因此我们常常使用的是先利用getElementById()方
法获取到指定位置的元素节点。再利用getElemntsBytagName()方法来获取字节点数组。这是我们推荐使用的。
(2)firstChild()方法和lastChild()方法
firstChild()方法用于获取当前元素节点的第一个字节点对象,相当于childNodes[0];lastChild()方法用于获取当前
元素节点的最后一个字节点对象。相当于childNodes[childNodes.length-1]。相同的在这里我们得到可能是文本子节点
对象或元素子节点对象,得到它们我们就能够使用那三个节点属性对它们进行操作。
实例:<span style="font-size:18px;"><span style="font-size:18px;">//获取id="city"的元素节点 var cityNode=document.getElementById("city"); //获取cityNode元素节点的第一个和最后一个子节点 alert(cityNode.firstChild);//返回:object Text表示文本节点对象 alert(cityNode.lastChild);//返回:object Text表示文本节点对象 alert(cityNode.lastChild.nodeName);//返回:#text</span></span>
(3)parentNode属性,prevousSlbling属性和nextSibling属性
parentNode属性返回该节点的父节点,prevousSlbling属性返回该节点的前一个同级节点,nextSibling属性返回
该节点的后一个同级节点。
实例:
<span style="font-size:18px;"><span style="font-size:18px;">//获取id="bj"的元素节点 var bjNode=document.getElementById("bj"); //获取bjNode元素节点的父节点 alert(bjNode.parentNode);//返回:object HTMLUListElement alert(bjNode.parentNode.nodeName);//返回:UL alert(bjNode.previousSibling);//返回:object text(由于id="bj"的元素节点的前一个是空白文本节点) alert(bjNode.nextSibling);//返回:object text</span></span>
上面总是提到空白文本节点,这个在IE浏览器中会自己主动回避。可是其他的浏览会输出。那么我们怎么样做才干让
它们兼容保持一致呢?这个须要我们手动移除:
<span style="font-size:18px;"><span style="font-size:18px;">//获取id="city"的元素节点 var cityNodes=document.getElementById("city"); //获取元素节点的全部子节点 alert(removeSpace(cityNodes.childNodes).length);//返回:4, function removeSpace(node) { for(var i=0;i<node.length;i++){ if(node[i].nodeType===3&&/^\s+$/.test(node[i].nodeValue)){ node[i].parentNode.removeChild(node[i]); } } return node; }</span></span>
从上面返回的结果来看我们得到了我们想要的结果。这种兼容性也非常好。跟用getElementsByTagName()方法
获取元素子节点的个数是一样的。
那么我们在获取第一个子节点和最后一个子节点后以及前一个同级节点与后一个同
级节点的时候相同的遇到了空文本节点的情况,也能够移除,仅仅需将上面的方法改进一下就可以:
<span style="font-size:18px;"><span style="font-size:18px;">//获取id="city"的元素节点 var cityNodes=document.getElementById("city"); //获取元素节点的全部子节点 alert(removeSpace(cityNodes).firstChild.nodeName);//返回:LI function removeSpace(node) { for(var i=0;i<node.childNodes.length;i++){ if(node.childNodes[i].nodeType===3&&/^\s+$/.test(node.childNodes[i].nodeValue)){ node.childNodes[i].parentNode.removeChild(node.childNodes[i]); } } return node; }</span></span>
以下部分部分算是获取属性节点
(4)attributes属性
attributes属性返回该节点的属性节点集合。attributes[0]表示的是最有一个节点,数组遍历的时候是从后向前的,
这里要注意。
实例:
<span style="font-size:18px;"><span style="font-size:18px;">//获取id="bj"的元素节点 var bjNode=document.getElementById("bj"); //使用attributes属性 alert(bjNode.attributes);//返回:object NameNodeMap alert(bjNode.attributes.length);//返回:4表示属性节点个数 alert(bjNode.attributes[3]);//返回:Attr.从后向前遍历 alert(bjNode.attributes[3].nodeType)//返回:2,表示属性节点 alert(bjNode.attributes[3].nodeName)//返回:id</span></span>
说明:
1)该属性在IE,火狐或谷歌上执行一样,也不知道是浏览器的原因。在2345浏览器遍历结果是相反的。可
能是不兼容吧。这里算是一个疑问吧?
2)假设向获取属性的的值而且改变,我们推荐使用上一篇博文提到的方法,可是要注意我们使用为符合标准的
name属性是不兼容的,name属性一般在表单元素中使用,其余的没有自己定义的name属性:
<span style="font-size:18px;"><span style="font-size:18px;">//获取id="bj"的元素节点 var bjNode=document.getElementById("bj"); //直接使用属性 alert(bjNode.id);//返回:bj alert(bjNode.style.color);//返回:red</span></span>
这两篇博文说了这么多。总结一下我们常常使用的方法(算上上一篇博文):
一获取元素节点常常使用的方法:(1)使用getElementById()方法通过id属性获取相应的单个元素节点。推荐使用。
(2)使用getElementByTagName()方法依据标签获取指定元素节点名字的数组,数组对象length属性能够获取数组
的长度。推荐使用。
(3)使用getElementsByName()方法依据name属性获取相应的表单元素节点。这里要注意是符合的表单元素中的
name属性的值。获取表单元素时推荐使用。
二获取元素节点的子节点(仅仅有元素节点才有子节点)我们通常使用
(1)首先是先利用获取元素节点的方法获取到元素节点。再使用childNodes属性获取所有的子节点对象数组列表。
注意不兼容性和空白文本节点。不推荐使用。
(2)首先是先利用获取元素节点的方法获取到元素节点,再使用firstChild属性与lastChild属性获取元素节点的第一
个子节点和最后一个子节点。
这里也要注意空白文本节点。推荐使用。
(3)首先利用获取元素节点的方法获取元素节点,再利用children属性获取全部它的全部有效子节点对象数组列
表。推荐使用。
(4)首先使用获取元素节点的方法获取到指定的元素节点,再使用getElemensByTagName()方法获取全部的子元
素节点对象数组列表。推荐使用。
三获取属性节点
(1)因为属性节点时某一指定元素节点的属性,能够通过先使用getElementById()方法通过id属性获取相应的单个
元素节点再利用“元素节点.属性”这种方式来获取和设置属性节点的值。推荐使用。
(2)先利用获取元素节点的方法获取到元素节点,再使用Attribute属性返回该节点的属性节点集合。可是要注意浏
览器的兼容性。这样的不推荐使用。
四获取文本节点(文本节点时元素节点的子节点)(1)首先也是利用获取元素节点的方法获取到元素节点,再利用元素节点的属性innerHTML属性得到文本节点中的
文本内容。推荐使用。
(2)假设指定的元素节点中仅仅有一个子节点。也就是该子节点是文本节点。能够先获取文本节点所在的元素节点,
再利用firstChild属性定位到文本节点,最后通过文本节点的nodeValue属性获取文本节点中的文本内容。推荐。
五获取body元素节点
(1)使用document.getElemensByTagName("body")[0]获取body元素节点。
(2)使用document.body获取body元素节点。
推荐使用。