前面的话

  元素节点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()方法返回一个布尔值,表示当前元素节点是否包含指定属性

  [注意]IE7-浏览器不支持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、contenteditable这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-浏览器下对象属性和元素特性的混淆bug来设置

<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>

最后

  如果从头到尾看完这篇博文,会发现全篇篇幅最多的内容是特性的设置。特性设置不是应该在特性节点上吗?特性节点可以设置,但是使用元素节点来操作特性更方便。元素节点的内容还包括元素节点的操作,但是由于在节点操作博文中已经详细介绍过,就不再赘述

  下一篇将介绍特性节点

  欢迎交流

深入理解DOM节点类型第五篇——元素节点Element的更多相关文章

  1. 深入理解DOM节点类型第六篇——特性节点Attribute

    × 目录 [1]特征 [2]属性 [3]方法 前面的话 元素的特性在DOM中以Attr类型表示,从技术角度讲,特性是存在于元素的attributes属性中的节点.尽管特性是节点,但却不是DOM节点树的 ...

  2. 深入理解DOM节点类型第三篇——注释节点和文档类型节点

    × 目录 [1]注释节点 [2]文档类型 前面的话 把注释节点和文档类型节点放在一起是因为IE8-浏览器的一个bug.IE8-浏览器将标签名为"!"的元素视作注释节点,所以文档声明 ...

  3. 深入理解DOM事件类型系列第一篇——鼠标事件

    × 目录 [1]类型 [2]顺序 [3]坐标位置[4]修改键[5]相关元素[6]鼠标按键[7]滚轮事件[8]移动设备 前面的话 鼠标事件是web开发中最常用的一类事件,毕竟鼠标是最主要的定位设备.本文 ...

  4. 深入理解DOM事件类型系列第二篇——键盘事件

    × 目录 [1]类型 [2]顺序 [3]按键信息[4]应用 前面的话 鼠标和键盘是电脑端主要的输入设备,上篇介绍了鼠标事件,本文将详细介绍键盘事件 类型 键盘事件用来描述键盘行为,主要有keydown ...

  5. 深入理解DOM节点类型第七篇——文档节点DOCUMENT

    × 目录 [1]特征 [2]快捷访问 [3]文档写入 前面的话 文档节点document,隶属于表示浏览器的window对象,它表示网页页面,又被称为根节点.本文将详细介绍文档节点document的内 ...

  6. 深入理解DOM节点类型第四篇——文档片段节点DocumentFragment

    × 目录 [1]特征 [2]作用 前面的话 在所有节点类型中,只有文档片段节点DocumentFragment在文档中没有对应的标记.DOM规定文档片段(document fragment)是一种“轻 ...

  7. 深入理解DOM事件类型系列第三篇——变动事件

    × 目录 [1]删除节点 [2]插入节点 [3]特性节点[4]文本节点 前面的话 变动(mutation)事件能在DOM中的某一部分发生变化时给出提示,这类事件非常有用,但都只能使用DOM2级事件处理 ...

  8. 深入理解DOM事件类型系列第五篇——文本事件

    × 目录 [1]change [2]textInput [3]input[4]propertychange[5]兼容 前面的话 如果DOM结构发生变化,触发的是变动事件:如果文本框中的文本发生变化,触 ...

  9. 深入理解DOM事件类型系列第四篇——剪贴板事件

    × 目录 [1]定义 [2]对象方法 [3]应用 前面的话 剪贴板操作可能看起来不起眼,但是却十分有用,可以增强用户体验,方便用户操作.本文将详细介绍剪贴板事件 定义 剪贴板操作包括剪切(cut).复 ...

随机推荐

  1. linux下使用shell 自动执行脚本文件

    以下实例本人在Centos6.5 64位操作系统中使用 一.定时复制文件 a.在/usr/local/wfjb_web_back目录下创建 tomcatBack.sh文件 文件内容: #将tomcat ...

  2. 借助 SIMD 数据布局模板和数据预处理提高 SIMD 在动画中的使用效率

    原文链接 简介 为发挥 SIMD1 的最大作用,除了对其进行矢量化处理2外,我们还需作出其他努力.可以尝试为循环添加 #pragma omp simd3,查看编译器是否成功进行矢量化,如果性能有所提升 ...

  3. 马哥linux运维初级+中级+高级 视频教程 教学视频 全套下载(近50G)

    马哥linux运维初级+中级+高级 视频教程 教学视频 全套下载(近50G)目录详情:18_02_ssl协议.openssl及创建私有CA18_03_OpenSSH服务及其相关应用09_01_磁盘及文 ...

  4. Linux CentOS7通过yum命令安装Mono(尝先安装模式)

    前言 经过尝试网上各种安装mono的技术贴,这个安装过程经历了大约2周,尝试了各个版本,几目前博客所描述的所有安装方式.以下内容的安装方式可以为你尝试不同版本的mono.并非正式环境安装标准方式安装. ...

  5. ASP.NET MVC Model元数据(一)

    ASP.NET MVC Model元数据(一) 前言 在我初学的时候对Model元数据的概念很模糊,或者说是在大脑中没有它的一个模型,作为小白的我去看网上的一些文章还是两眼一黑啥都看不明白,然后我想退 ...

  6. React-Native 动画优化

    前言 动画对于客户端来说是非常重要的一部分,直接影响到应用的用户体验.前端对于动画优化通常使用CSS3样式来实现动画,以利用GPU加速特性.而React-Native由于渲染模式的不同,无法使用CSS ...

  7. javascript中的浮点数运算

    解释一下下面代码的输出 console.log(0.1 + 0.2); //0.30000000000000004 console.log(0.1 + 0.2 == 0.3); //false Jav ...

  8. Java Thread 的 sleep() 和 wait() 的区别

    Java Thread 的使用 Java Thread 的 run() 与 start() 的区别 Java Thread 的 sleep() 和 wait() 的区别       1. sleep ...

  9. MVVM下listbox默认显示最后一行

    原文地址:http://stackoverflow.com/questions/16866309/listbox-scroll-into-view-with-mvvm public class Scr ...

  10. 别语言之争了,最牛逼的语言不是.NET,也不是JAVA!

    谁都不用说,博客园明显的偏.NET,C#的讨论一出现,推荐讨论热火朝天,而发点JAVA的东西,应者寥寥.一旦有出现两大派系的竞争,那绝对是头条.每天都看,早就麻木了. 研二的我浸淫.NET已经三四年, ...