知识铺垫:
节点(node)包括:
元素:Element标签
元素的属性: prototype属性
元素的内容:text文本
注释信息:
节点的属性
节点属性 | 元素 | 标签属性 | 文本内容 | 注释 |
---|---|---|---|---|
.nodeType | 1 | 2 | 3 | 8 |
.nodeName | 大写的标签名 | 小写的属性名 | #text | #comment |
.nodeValue | null | 属性值 | 文本内容 | 注释内容 |
子节点childNodes
包含内容
高级浏览器中:
标签
文本text
(文本内容 or 空格 or 换行)注释comment
;
低版本浏览器:标签
文本text
(文本内容,不包括空格和换行)注释comment
;
子元素 children
高级浏览器中:只能获取标签
低版本浏览器:可以获取标签和注释,如果只想获取标签还需要判断过滤掉注释
用原生js封装 firstElementChild
/ lastElementChild
/ nextSibling
/ previousElementSibling
几个获取子元素标签的方法,解决在低版本浏览器中不兼容的问题。
在高级浏览器中可以正常读取子元素标签,然而在低版本浏览器中会报undefined
。
获取元素的第一个子元素:
html结构部分
<div id="box">
<h1 id="h1" title="你是谁">周</h1>
<!-- R&B曲风 -->
<ul id="list">
哈哈
<!--注释1-->
<!--注释2-->
<!--注释3-->
<li>歌曲1</li>
<li>歌曲2</li>
<li>歌曲3</li>
<li>歌曲4</li>
<li>歌曲5</li>
</ul>
<h2>方文山</h2>
</div>
js部分,具体请看注释说明
firstElementChild
第一个子元素 只有高级浏览器能使用
firstChild
第一个子节点 获取的是节点
var list = document.getElementById('list');
/**
* 封装获取元素的第一个子节点
* @param {元素对象} obj
*/
function getFirstElementChild(obj){
// 若第一个子元素为真,表示用户使用的高级浏览器可以解析该属性,则使用firstElementChild来获取第一个子元素.
if(obj.firstElementChild){
return obj.firstElementChild;
}else{ //否则 ,就循环所有的子节点,判断其`.nodeType`属性是否=1.(节点.nodeType=1表示该节点是标签元素)
var nodeE = obj.firstChild; //将第一个子节点赋值给变量nodeE
// 如果obj没有子节点,obj.firstChild获取就是null
//如果nodeE中有数据,nodeE就是true,再判断&&后面的条件
//如果nodeE中是null,nodeE就是false,不再判断&&后面的条件
while(nodeE.nodeType !=1){ //循环所有子节点,当子节点的nodeType不等于1时,进入循环
nodeE = nodeE.nextSibling; //将下一个兄弟节点赋值给变量nodeE,直到找到第一个子元素,循环结束
}
return nodeE; // 返回第一个子节点==第一个子元素子.
}
}
// 调用封装好的方法
var ele = getFirstElementChild(list);
console.log(ele); //控制台输出<li>歌曲1</li>
获取元素的最后一个子元素:
html部分
<div id="box">呵呵
<h1 title="我是标题" id="h1">周</h1>
<!-- R&B曲风 -->
<ul id="list">
哈哈
<!--注释1-->
<!--注释2-->
<!--注释3-->
<li>歌曲1</li>
<li>歌曲2</li>
<li>歌曲3</li>
<li>歌曲4</li>
<li>歌曲5</li>
<!--注释1-->
<!--注释2-->
<!--注释3-->
嘿嘿
</ul>
<h2>方文山</h2>
</div>
js部分,具体请看注释说明
var list =document.getElementById('list');
/**
* 封装最后一个子元素
* @param {元素对象} obj
*/
function getLastElementChild(obj){
if(obj.lastElementChild){
return obj.lastElementChild;
}else{
var nodeE = obj.lastChild;
// 如果obj没有子节点,obj.lastChild 获取就是null;
//如果nodeE中有数据,nodeE就是true,再判断&&后面的条件;
//如果nodeE中是null,nodeE就是false,不再判断&&后面的条件.
while(nodeE && nodeE.nodeType!=1 ){
nodeE = obj.previousSibling; //将上一个兄弟节点赋值给变量nodeE,直到找到最后一个子元素,循环结束
}
return nodeE;
}
}
//调用并输出 最后一个子元素
console.log(getLastElementChild(list)); //控制台输出 <li>歌曲5</li>
获取元素的下一个兄弟元素:
html部分
<div id="box">呵呵
<h1 title="我是标题" id="h1">周</h1>
<!-- R&B曲风 -->
<ul id="list">
<li>歌曲1</li>
<li>歌曲2</li>
<li id='li03'>歌曲3</li>
<!--注释1-->
<!--注释2-->
<!--注释3-->
<li>歌曲4</li>
<li>歌曲5</li>
</ul>
<h2>方文山</h2>
</div>
js部分
var lo03=document.getElementById('li03');
/**
* 封装下一个兄弟元素
* @param {元素对象} obj
*/
function getNextElementSibling(obj){
if(obj.nextElementSibling){ //如果用户使用的是高级的浏览器则为真,否则为假.
return obj.nextElementSibling;
}else{
var nodeE = obj.nextSibling;
while(nodeE && nodeE.nodeType!=1){ //判断子节点不为空,则循环所有子节点的nodeType属性,如果=1则返回nodeE,不为1就将下一个兄弟节点赋值给nodeE
nodeE = nodeE.nextSibling;
}
return nodeE;
}
}
// 调用并输出下一个兄弟元素
console.log(getNextElementSibling(li03)); //控制台输出 <li>歌曲4</li>
获取元素的上一个兄弟元素:
htm部分
<div id="box">呵呵
<h1 title="我是标题" id="h1">周</h1>
<!-- R&B曲风 -->
<ul id="list">
<li>歌曲1</li>
<!--注释1-->
<!--注释2-->
<!--注释3-->
<li>歌曲2</li>
<li id='li03'>歌曲3</li>
<!--注释1-->
<!--注释2-->
<!--注释3-->
<li>歌曲4</li>
<li>歌曲5</li>
</ul>
<h2>方文山</h2>
</div>
js部分
var li03 = document.getElementById('li03');
/**
* 封装上一个兄弟元素
* @param {元素对象} obj
*/
function getPreElementSibling(obj){
if(obj.previousElementSibling){
return obj.previousElementSibling;
}else{
var nodeE = obj.previousSibling;
while(nodeE && nodeE.nodeType !=1){
nodeE = nodeE.previousSibling;
}
return nodeE;
}
}
//调用并输出上一个兄弟元素
console.log(getPreElementSibling(li03)); //控制台输出 <li>歌曲2</li>