深入理解DOM节点类型第五篇——元素节点Element
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
深⼊理解DOM节点类型第五篇——元素节点Element
前⾯的话
元素节点Element⾮常常⽤,是DOM⽂档树的主要节点;元素节点是html标签元素的DOM化结果。
元素节点主要提供了对元素标签名、⼦节点及特性的访问,本⽂将详细介绍元素节点的主要内容
特征
元素节点的三个node属性——nodeType、nodeName、nodeValue分别是1、元素的⼤写标签名和null,其⽗节点parentNode指向包含该元素节点的元素节点Element或⽂档节点Document
[注意]要访问元素的标签名可以使⽤nodeName,也可以使⽤tagName属性,这两个属性会返回相同的值
<div id="test">123</div>
<script>
console.log(test.nodeType);//1
console.log(test.nodeName);//'DIV'
console.log(test.nodeValue);//null
console.log(test.parentNode);//<body>
console.log(test.childNodes);//[text]
console.log(test.tagName,test.tagName === test.nodeName);//'DIV' true
</script>
⼦节点
元素可以有任意数⽬的⼦节点和后代节点,因为元素可以是其他元素的⼦节点。
元素的childNodes属性中包含了它的所有⼦节点,这些⼦节点可能是元素、、、处理指令节点
<ul class="list" id="list">
<li class="in"></li>
<li class="in"></li>
</ul>
<script>
var oList = document.getElementById('list');
//IE8-浏览器返回2,其他浏览器返回5。
因为IE8-浏览器⼦节点中不包含空⽩⽂本节点
//关于空⽩⽂本节点的详细内容
console.log(oList.childNodes.length)
</script>
兼容
可以通过检查nodeType属性来只获取元素节点
<ul class="list" id="list">
<li class="in"></li>
<li class="in"></li>
</ul>
<script>
var oList = document.getElementById('list');
var children = oList.childNodes;
var num = 0;
for(var i = 0; i < children.length; i++){
if(children[i].nodeType == 1){
num++;
}
}
console.log(num);//2
</script>
特性操作
每个元素都有⼀或多个特性,这些特性的⽤途是给出相应元素或其内容的附加信息。
操作特性的DOM⽅法主要有hasAttribute()、getAttribute()、setAttribute()、removeAttribute()四个,可以针对任何特性使⽤,包括那些以HTMLElement类型属性的形式定义的特性hasAttribute()
hasAttribute()⽅法返回⼀个布尔值,表⽰当前元素节点是否包含指定属性
<div id="test" class="class1"></div>
<script>
console.log(test.hasAttribute('class'));//true
console.log(test.hasAttribute('title'));//false
</script>
getAttribute()
getAttribute()⽅法⽤于取得特性的值,如果给定名称的特性不存在或⽆参数则返回null
<div id="test" class="class1"></div>
<script>
console.log(test.getAttribute('class'));//'class1'
console.log(test.getAttribute('title'));//null
console.log(test.getAttribute('b'));//null
console.log(test.getAttribute(''));//null
</script>
[注意]元素特性和对象属性并不相同,⼆者的区别详细情况
setAttribute()
setAttribute()⽅法接受两个参数:要设置的特性名和值,如果已经存在,则替换现有的值。
如果特性不存在,setAttribute()则创建该属性并设置相应的值。
该⽅法⽆返回值
<div id="box">123</div>
<script>
var oBox = document.getElementById('box');
oBox.setAttribute("id","test");
//注意获取oBox.id时并不会报错,因为oBox保存的是当时id为box的对象,也就是现在id为test的对象
console.log(oBox.id);//test
</script>
[注意]通过setAttrbute()⽅法设置的特性名会统⼀转换成⼩写形式
<div id="box">123</div>
<script>
var oBox = document.getElementById('box');
oBox.setAttribute("ABC","test");
console.log(oBox.getAttribute("ABC"));//test
console.log(oBox.getAttribute("abc"));//test
</script>
bug
IE7-浏览器设置class、style、for、cellspacing、cellpadding、tabindex、readonly、maxlength、rowspan、colspan、usemap、frameborder、contnenteditable这13个特性没有任何效果
<style>
.testClass{
font-size: 30px;
}
</style>
<div id="box">123</div>
<script>
//IE7-浏览器下没有任何效果,其他浏览器出现红⾊背景及30px的⽂字⼤⼩
var oBox = document.getElementById('box');
oBox.setAttribute("class","testClass");
oBox.setAttribute("style","height: 100px; background: red;")
</script>
可以利⽤IE7-浏览器下对象属性和元素特性的来设置
<style>
.testClass{
font-size: 30px;
}
</style>
<div id="box">123</div>
<script>
var oBox = document.getElementById('box');
oBox.setAttribute("class","testClass");
oBox.setAttribute("style","height: 100px; background: red;");
//IE7下oBox.className的值为undefined
if(!oBox.className){
oBox.setAttribute("className","testClass");
oBox.style.setAttribute("cssText","height: 100px; background: red;");
}
</script>
removeAttribute()
removeAttribute()⽅法⽤于彻底删除元素的特性,这个⽅法不仅会彻底删除元素的特性值,还会删除元素特性。
该⽅法⽆返回值
<div class="box" id="box"></div>
<script>
var oBox = document.getElementById('box');
console.log(oBox.getAttribute("id"));//box
console.log(oBox.removeAttribute("id"));//undefined
console.log(oBox.getAttribute("id"));//null
</script>
attributes属性
元素节点Element是使⽤attributes属性的唯⼀⼀个DOM节点类型。
attributes属性中包含⼀个NamedNodeMap,与NodeList类似,也是⼀个动态的集合。
元素的每⼀个特性都由⼀个Attr节点表⽰,每个节点都保存在NamedNodeMap对象中,每个节点的nodeName就是特性的名称,节点的nodeValue就是特性的值
attributes属性包含以下四个⽅法
getNamedItem(name)
getNamedItem(name)⽅法返回nodeName属性等于name的节点
<div class="box" id="box" name="abc" index="123" title="test"></div>
<script>
var oBox = document.getElementById('box');
console.log(oBox.attributes);//NamedNodeMap {0: class, 1: id, 2: name, 3: index, 4: title}
console.log(oBox.attributes.getNamedItem("index"));//index='123'
console.log(oBox.attributes.getNamedItem("index").nodeName);//'index'
console.log(oBox.attributes.getNamedItem("index").nodeValue);//'123'
console.log(oBox.attributes.index);//index='123'
</script>
removeNamedItem(name)
removeNamedItem(name)⽅法从列表中移除nodeName属性等于name的节点,并返回该节点
<div class="box" id="box" name="abc" index="123" title="test"></div>
<script>
var oBox = document.getElementById('box');
console.log(oBox.attributes);//NamedNodeMap {0: class, 1: id, 2: name, 3: index, 4: title}
console.log(oBox.attributes.getNamedItem("index"));//index='123'
console.log(oBox.attributes.removeNamedItem("index"));//index='123'
console.log(oBox.attributes.getNamedItem("index"));//null
</script>
setNamedItem(node)
setNamedItem(node)⽅法向列表中添加节点,该⽅法⽆返回值
<div class="box" id="box" name="abc" index="123" title="test"></div>
<script>
var oBox = document.getElementById('box');
console.log(oBox.attributes);//NamedNodeMap {0: class, 1: id, 2: name, 3: index, 4: title}
var oldItem = oBox.attributes.removeNamedItem("index");
console.log(oBox.attributes.getNamedItem("index"));//null
console.log(oldItem);//index='123'
console.log(oBox.attributes.setNamedItem(oldItem));//null
console.log(oBox.attributes.getNamedItem("index"));//index='123'
</script>
item(pos)
item(pos)⽅法返回位于数字pos位置处的节点,也可以⽤⽅括号法[]简写
<div class="box" id="box" name="abc" index="123" title="test"></div>
<script>
var oBox = document.getElementById('box');
console.log(oBox.attributes);//NamedNodeMap {0: class, 1: id, 2: name, 3: index, 4: title}
console.log(oBox.attributes.item(2));//name="abc"
console.log(oBox.attributes[2]);//name="abc"
</script>
遍历
attributes属性主要⽤于特性遍历。
在需要将DOM结构序列化为HTML字符串时,多数都会涉及遍历元素特性
function outputAttributes(element){
var pairs = new Array(),attrName,attrValue,i,len;
for(i = 0,len=element.attributes.length;i<len;i++){
attrName = element.attributes[i].nodeName;
attrValue = element.attributes[i].nodeValue;
pairs.push(attrName +"=\"" + attrValue + "\"");
}
return pairs.join(" ");
}
针对attributes对象中的特性,不同浏览器返回的顺序不同
<div class="box" id="box" name="abc" index="123" title="test"></div>
<script>
function outputAttributes(element){
var pairs = new Array(),attrName,attrValue,i,len;
for(i = 0,len=element.attributes.length;i<len;i++){
attrName = element.attributes[i].nodeName;
attrValue = element.attributes[i].nodeValue;
pairs.push(attrName +"=\"" + attrValue + "\"");
}
return pairs.join(" ");
}
//(chrome\safari)class="box" id="box" name="abc" index="123" title="test"
//(firefox)title="test" index="123" name="abc" id="box" class="box"
//(IE8+)title="test" class="box" id="box" index="123" name="abc"
//(IE7-)输出所有的特性
console.log(outputAttributes(document.getElementById("box")))
</script>
由上⾯结果看出,IE7-浏览器会返回HTML元素中所有可能的特性,包括没有指定的特性
specified
可以利⽤特性节点的specified属性来解决IE7-浏览器的这个问题。
如果specified属性的值为true,则意味着该属性被设置过。
在IE中,所有未设置过的特性的该属性值都是false。
⽽在其他浏览器中,任何特性节点的specified值始终为true
<div id="box" name="abc" index="123" title="test"></div>
<script>
var oBox = document.getElementById('box');
var yesItem = oBox.attributes.getNamedItem("index");
var noItem = oBox.attributes.getNamedItem("onclick");
//所有浏览器浏览器都返回true
console.log(yesItem.specified);
//IE7-浏览器返回false,⽽其他浏览器报错,noItem不存在
console.log(noItem.specified);
</script>
<div class="box" id="box" name="abc" index="123" title="test"></div>
<script>
function outputAttributes(element){
var pairs = new Array(),attrName,attrValue,i,len;
for(i = 0,len=element.attributes.length;i<len;i++){
attrName = element.attributes[i].nodeName;
attrValue = element.attributes[i].nodeValue;
if(element.attributes[i].specified){
pairs.push(attrName +"=\"" + attrValue + "\"");
}
}
return pairs.join(" ");
}
//所有浏览器下都返回title="test" class="box" id="box" index="123" name="abc"(顺序不⼀样)
console.log(outputAttributes(document.getElementById("box")))
</script>
最后
如果从头到尾看完这篇博⽂,会发现全篇篇幅最多的内容是特性的设置。
特性设置不是应该在特性节点上吗?特性节点可以设置,但是使⽤元素节点来操作特性更⽅便。
元素节点的内容还包括元素节点的操作,但是由于在中已经详细介绍过,就不再赘述
下⼀篇将介绍特性节点
欢迎交流。