我们这里所说的获取元素节点的所有子节点包含元素子节点和文本节点两种。还是拿上一篇博文的代码实例进行
分析:
<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元素节点。推荐使用。