定义
每个元素都有一个或多个特性,这些特性的用途是给出相应元素或内容的附加信息。实质上,特性节点就是存在于元素的attributes属性中的节点。
特征
nodeType:2
nodeName:特性的名称
nodeValue:特性的值
parentNode:null
childNode:chrome、firefox下为undefined,safari下为Text,IE9+下为子元素的特性名,IE8-下报错
[注意]尽管Attribute也是节点,但却不被认为是DOM文档树的一部分,开发人员常用getAttribute()、setAttribute()、removeAttribute(),很少直接引用特性节点
<div id="box"></div> <script> var oBox = document.getElementById(‘box‘); var oAttr = oBox.attributes; //(chrome\safari\IE9+\firefox) 2 id box null //(IE7-) 2 onmsanimationiteration null null console.log(oAttr[0].nodeType,oAttr[0].nodeName,oAttr[0].value,oAttr[0].parentNode) //(chrome\firefox) undefined //(safari) Text //(IE9+) box //(IE8-) 报错 console.log(oAttr[0].childNodes[0]) </script>
特性节点属性
Attr对象有3个属性:name、value和specified
【1】name是特性名称(与nodeName的值相同)
【2】value是特性的值(与nodeValue的值相同)
【3】specified是一个布尔值,用以区别特性是在代码中指定的,还是默认的。这个属性的值如果为true,则意味着要么是在HTML中指定了相应特性,要么是通过setAttribute()方法设置了该属性。在IE中,所有未设置过的特性的该属性值都为false,而在其他浏览器中根本不会为这类特性生成对应的特性节点
<div class="box" id="box"></div> <script> var oBox = document.getElementById(‘box‘); var oAttr = oBox.attributes; //(chrome\safari\IE8+)class class true //(firefox)id id true //(IE7-)onmsanimationiteration onmsanimationiteration true console.log(oAttr[0].name,oAttr[0].nodeName,oAttr[0].name == oAttr[0].nodeName) //IE7- "null" null false //其他浏览器 box box true console.log(oAttr[0].value,oAttr[0].nodeValue,oAttr[0].value == oAttr[0].nodeValue) //IE7- false //其他浏览器 true console.log(oAttr[0].specified)//true </script>
<div class="box" id="box" name="abc" index="123" title="test"></div> <script> var oBox = document.getElementById(‘box‘); console.log(oBox.attributes.id.specified)//true console.log(oBox.attributes.onclick.specified)//在IE7-浏览器下会返回false,在其他浏览器下会报错 </script>
特性属性attributes
Element类型是使用attributes属性的唯一一个DOM节点类型。attributes属性中包含一个NamedNodeMap,与NodeList类似,也是一个动态的集合。元素的每一个特性都由一个Attr节点表示,每个节点都保存在NamedNodeMap对象中。
【attributes属性的四个方法】
[a]getNamedItem(name):返回nodeName属性等于name的节点
[b]removeNamedItem(name):从列表中移除nodeName属性等于name的节点
[c]setNamedItem(node):向列表中添加节点,以节点的nodeName属性为索引
[d]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} var getTest = oBox.attributes.getNamedItem("index"); console.log(getTest);//index = "123" var removeTest = oBox.attributes.removeNamedItem("class"); console.log(removeTest);//class = "box" console.log(oBox.attributes.getNamedItem("class"));//null console.log(oBox.attributes.setNamedItem(removeTest));//null console.log(oBox.attributes.setNamedItem(getTest));//index = "123" console.log(oBox.attributes.item(0));//id="box"(每个浏览器获取的不一样) </script>
attributes属性中包含一系列节点,每个节点的nodeName就是特性的名称,节点的nodeValue就是特性的值
<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.id.nodeName);//"id" console.log(oBox.attributes.id.nodeValue);//"box" </script>
【特性遍历】
attributes属性主要用于特性遍历。在需要将DOM结构序列化为XML或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(" "); }
[注意1]针对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>
[注意2]IE7-浏览器会返回HTML元素中所有可能的特性,包括没有指定的特性
【解决】利用特性节点的specified属性
<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>
特性节点方法
【1】createAttribute()方法传入特性名称并创建新的特性节点
【2】setAttributeNode()方法传入特性节点并将特性添加到元素上
【3】getAttributeNode()方法传入特性名并返回特性节点
【4】removeAttributeNode()方法传入特性名删除并返回删除的特性节点,但IE7-浏览器下无法删除
<div id="box"></div> <script> var oBox = document.getElementById(‘box‘); var attr = document.createAttribute(‘title‘); attr.value = "test"; oBox.setAttributeNode(attr); console.log(oBox.getAttributeNode("title").name,attr.name);//title title console.log(oBox.getAttributeNode("title").value,attr.value);//test test //返回删除的节点 console.log(oBox.removeAttributeNode(attr)); //IE7-浏览器下无法删除,其他浏览器返回null console.log(oBox.getAttributeNode("title")); </script>
特性方法
操作特性的DOM方法主要有getAttribute()、setAttribute()、removeAttribute()三个,可以针对任何特性使用,包括那些以HTMLElement类型属性的形式定义的特性
【1】getAttribute()方法
getAttribute()方法用于取得特性的值
<div class="boxClass" id="boxId" title="boxTitle" lang="en" dir="rtl">123</div> <script> var oBox = document.getElementById(‘boxId‘); console.log(oBox.getAttribute("class"))//boxClass console.log(oBox.getAttribute("id"))//boxId console.log(oBox.getAttribute("title"))//boxTitle console.log(oBox.getAttribute("lang"))//en console.log(oBox.getAttribute("dir"))//rtl </script>
[注意1]如果给定名称的特性不存在或无参数则返回null
console.log(oBox.getAttribute("abc"))//null console.log(oBox.getAttribute(""))//null
[注意2]传递给getAttribute()的特性名与实际的特性名相同,因此要得到class特性值,应该传入"class"而不是"className"。但IE7-浏览器却正好相反
console.log(oBox.getAttribute("class"))//boxClass,在IE7-浏览器下显示null console.log(oBox.getAttribute("className"))//在IE7-浏览器下显示boxClass,在其他浏览器下null
[注意3]通过getAttribute()可以取得自定义特性,但根据HTML5规范自定义特性应加上data-前缀以便验证
<div id="box" index="1" data-name="a">123</div> <script> var oBox = document.getElementById(‘box‘); console.log(oBox.getAttribute("index"))//1 console.log(oBox.getAttribute("data-name"))//a console.log(oBox.index);//IE7-显示1,其他浏览器显示undefined console.log(oBox.dataset.name);//IE10-不支持dataset,出错,其他浏览器显示a </script>
[注意4]IE8-浏览器不区分对象属性和元素特性。用对象属性的点方法可以获得自定义元素的特性。但对于元素特性中间存在中划线的情况,只能用中括号法来取得
<div id="box" data-name ="a" index = "1">123</div> <script> var oBox = document.getElementById(‘box‘); oBox.index = 2; //在IE8-浏览器下 console.log(oBox.dataName);//undefined console.log(oBox["data-name"]);//a console.log(oBox.index);//2 </script>
[注意5]有两类特殊的特性,它们虽然有对应的属性名,但属性的值与通过getAttribute()返回的值并不相同。由于以下这些差别,只有在取得自定义特性值的情况下,才会使用getAttribute()
[a]第一类特性是style,用于通过CSS为元素指定样式。在通过getAttribute()访问时,返回的style特性值中包含的是CSS文本,而通过属性来访问它则会返回一个对象。由于style属性是用于以编程方式访问元素样式的,因此并没有直接映射到style特性。
<div id="box" style="height: 100px; width: 100px;">123</div> <script> var oBox = document.getElementById(‘box‘); console.log(oBox.style);//CSS2Properties { height: "100px", width: "100px"} //在IE7-浏览器下返回的是oBox.style所取得的对象值。 //[注意]属性的顺序与所写的顺序可以不一致,每个浏览器显示的顺序不一样 console.log(oBox.getAttribute("style"))//"height: 100px; width: 100px;" </script>
[b]第二类特性是onclick这样的事件处理程序。当在元素上使用时,onclick特性中包含的是Javascript代码,如果通过getAttribute()访问,则会返回相应代码的字符串。而在访问onclick属性时,则会返回一个JavaScript函数(如果未在元素中指定相应特性,则返回null)
<div id="box" onclick = "alert(1)">123</div> <script> var oBox = document.getElementById(‘box‘); console.log(oBox.onclick);//function onclick(event){alert(1)} console.log(oBox.getAttribute("onclick"));//"alert(1)" </script>
【2】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>
[注意1]通过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>
[注意2]为DOM元素添加一个自定义属性,该属性不会自动成为元素的特性
<div id="box">123</div> <script> var oBox = document.getElementById(‘box‘); oBox.color = "red"; console.log(oBox.getAttribute("color"));//IE8-浏览器返回red,其他浏览器返回null </script>
[注意3]IE7-浏览器设置class、style、for、cellspacing、cellpadding、tabindex、readonly、maxlength、rowspan、colspan、usemap、frameborder、contnenteditable这13个特性没有任何效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .testClass{ font-size: 30px; } </style> </head> <body> <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> </body> </html>
【解决】可以利用IE8-浏览器下对象属性和元素特性混淆的bug来设置
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .testClass{ font-size: 30px; } </style> </head> <body> <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> </body> </html>
【3】removeAttribute()
该方法用于彻底删除元素的特性,这个方法不仅会彻底删除元素的特性值,还会删除元素特性
<div class="box" id="box"></div> <script> var oBox = document.getElementById(‘box‘); console.log(oBox.getAttribute("id"));//box oBox.removeAttribute("id"); console.log(oBox.getAttribute("id"));//null </script>