JS 10.1 节点层次

10 dom

DOM(文档对象模型)是针对HTML 和XML 文档的一个API(应用程序编程接口);

DOM描绘了一个层次化的节点树,允许开发人员添加,移除和修改页面的某一部分;

IE中的所有DOM对象都是以COM对象的形式实现的;

这意味着IE中的DOM对象与原生JavaScript对象的行为或活动特点并不一致;

本章将较多地谈及这些差异;

IE真是灿烂的烟火惹;

10.1 节点层次

文档元素是文档的最外层元素,文档中的其他所有元素都包含在文档元素中;

在HTML页面中,始终就是<html>,XML中,没有预定义的元素,随便哪个都可能是文档元素;

Node类型

每个节点都有一个nodeType属性表名节点类型;

节点类型用12个数值常量来表示,任何节点类型必居其一;

Node.ELEMENT_NODE(1);
Node.ATTRIBUTE_NODE(2);
Node.TEXT_NODE(3);
Node.CDATA_SECTION_NODE(4);
Node.ENTITY_REFERENCE_NODE(5);
Node.ENTITY_NODE(6);
Node.PROCESSING_INSTRUCTION_NODE(7);
Node.COMMENT_NODE(8);
Node.DOCUMENT_NODE(9);
Node.DOCUMENT_TYPE_NODE(10);
Node.DOCUMENT_FRAGMENT_NODE(11);
Node.NOTATION_NODE(12);

但是以上在IE是不行的,IE也没有公开自己的Node类型构造函数,所以;

if (someNode.nodeType == Node.ELEMENT_NODE) { //在IE 中无效
    alert("Node is an element.");
}

if (someNode.nodeType == 1) { //适用于所有浏览器
    alert("Node is an element.");
}

nodeName和nodeValue

这两个值完全取决于节点的类型;

if (someNode.nodeType == 1) {
    value = someNode.nodeName; //nodeName 的值是元素的标签名
}

节点关系

每个节点都有一个childNodes属性,其中保存着一个NodeList对象;

NodeList是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点;

注意,虽然可以通过方括号语法来访问NodeList的值,而且这个对象也有length属性,但它并不是Array的实例;

NodeList对象的独特之处在于,它实际上是基于DOM结构动态执行查询的结果;

因此DOM结构的变化能够自动反映在NodeList对象中;

我们常说,NodeList是有生命,有呼吸的对象,而不是在我们第一次访问它们的某个瞬间拍摄下来的一张快照;

var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;

将NodeList转为数组;

function convertToArray(nodes) {
    var array = null;
    try {
        array = Array.prototype.slice.call(nodes, 0); //针对非IE浏览器
    } catch (ex) {
        array = new Array();
        for (var i = 0, len = nodes.length; i < len; i++) {
            array.push(nodes[i]);
        }
    }
    return array;
}

是的,IE又闪耀自己了;

由于IE8及更早版本将NodeList实现为一个COM对象;

要想在IE中将NodeList转换为数组,必须手动枚举所有成员;

parentNode指向父节点;

childNodes列表中的每个节点相互是同胞节点;

第一个节点的previousSibling属性值为null;

最后一个节点的nextSibling属性值也为null;

如果只有一个节点,两个都是null;

如果没有子节点,firstChild和lastChild的值均为null;

hasChildNodes()在节点包含一或多个子节点的情况下返回true;

应该说,这是比查询childNodes列表的length属性更简单的方法;

所有节点都有的最后一个属性是ownerDocument,该属性指向表示整个文档的文档节点;

虽然所有节点类型都继承自Node,但并不是每种节点都有子节点;

操作节点

appendChild()添加到末尾,如果已经是文档的一部分,则移动到末尾;

insertBefore()插入某特定位置;

这个方法接受两个参数:要插入的节点和作为参照的节点;

插入节点后,被插入的节点会变成参照节点的前一个同胞节点(previousSibling),同时被方法返回;

如果参照节点是null,则insertBefore()与appendChild()执行相同的操作;

//插入后成为最后一个子节点
returnedNode = someNode.insertBefore(newNode, null);
alert(newNode == someNode.lastChild); //true
//插入后成为第一个子节点
var returnedNode = someNode.insertBefore(newNode, someNode.firstChild);
alert(returnedNode == newNode); //true
alert(newNode == someNode.firstChild); //true
//插入到最后一个子节点前面
returnedNode = someNode.insertBefore(newNode, someNode.lastChild);
alert(newNode == someNode.childNodes[someNode.childNodes.length - 2]); //true

replaceChild()方法接受的两个参数是:要插入的节点和要替换的节点;

要替换的节点将由这个方法返回并从文档树中被移除,同时由要插入的节点占据其位置;

//替换第一个子节点
var returnedNode = someNode.replaceChild(newNode, someNode.firstChild);
//替换最后一个子节点
returnedNode = someNode.replaceChild(newNode, someNode.lastChild);

removeChild()接受一个参数,即要移除的节点;被移除的节点将成为方法的返回值;

在使用replaceChild()插入一个节点时,该节点的所有关系指针都会从被它替换的节点复制过来;

尽管从技术上讲,被替换的节点仍然还在文档中,但它在文档中已经没有了自己的位置;

removeChild():俺也一样;

并不是所有类型的节点都有子节点,如果在不支持子节点的节点上调用了这些方法,将会导致错误发生;

其他方法

所有类型的节点都有的方法:cloneNode(),normalize();

cloneNode()方法接受一个布尔值参数,表示是否执行深复制;

在参数为true的情况下,执行深复制,也就是复制节点及其整个子节点树;

在参数为false的情况下,执行浅复制,即只复制节点本身;

复制后返回的节点副本属于文档所有,但并没有为它指定父节点;

var deepList = myList.cloneNode(true);
alert(deepList.childNodes.length); //3(IE < 9)或7(其他浏览器)
var shallowList = myList.cloneNode(false);
alert(shallowList.childNodes.length); //0

下面是IE登场了;

deepList.childNodes.length中的差异主要是因为IE8及更早版本与其他浏览器处理空白字符的方式不一样;

IE9之前的版本不会为空白符创建节点;

cloneNode()方法不会复制添加到DOM节点中的JavaScript属性,例如事件处理程序等;

这个方法只复制特性,(在明确指定的情况下也复制)子节点,其他一切都不会复制;

IE在此存在一个bug,即它会复制事件处理程序,所以我们建议在复制之前最好先移除事件处理程序;

normalize(),这个方法唯一的作用就是处理文档树中的文本节点;

由于解析器的实现或DOM操作等原因,可能会出现文本节点不包含文本;

或者接连出现两个文本节点的情况;

当在某个节点上调用这个方法时,就会在该节点的后代节点中查找上述两种情况;

如果找到了空文本节点,则删除它;

如果找到相邻的文本节点,则将它们合并为一个文本节点;

Document类型

在浏览器中,document对象是HTMLDocument,继承自Document类型的一个实例,表示整个HTML页面;

document对象是window对象的一个属性,可以作为全局对象来访问;

document节点特征:

1.nodeType的值为9;

2.nodeName的值为”#document”;

3.nodeValue的值为null;

4.parentNode的值为null;

5.ownerDocument的值为null;

6.其子节点可能是一个DocumentType(最多一个),Element(最多一个),ProcessingInstruction或Comment;

文档的子节点

document内置两个访问子节点的快捷方式:documentElement和childNodes;

documentElement始终指向HTML页面中的<html>元素;

childNodes列表访问文档元素,但documentElement属性可以更快捷,更直接地访问该元素;

document对象还有一个body属性,直接指向<body>元素;

Document另一个可能的子节点是DocumentType;

通常将<!DOCTYPE>标签看成一个与文档其他部分不同的实体;

可以通过doctype属性(在浏览器中是document.doctype)来访问它的信息;

浏览器对document.doctype 的支持差别很大,详情看PDF第272页吧(

文档信息

document独有的属性;

//取得文档标题
var originalTitle = document.title;
//设置文档标题
document.title = "New page title";
//取得完整的URL
var url = document.URL;
//取得域名
var domain = document.domain;
//取得来源页面的URL
var referrer = document.referrer;

在没有来源页面的情况下,referrer属性中可能会包含空字符串;

所有这些信息都存在于请求的HTTP头部,只不过是通过这些属性让我们能够在JavaScript中访问它们而已;

在URL,domain,referrer这3个属性中,只有domain是可以设置的;

但由于安全方面的限制,也并非可以给domain设置任何值;

如果URL中包含一个子域名,例如p2p.wrox.com,那么就只能将domain设置为”wrox.com”;

URL中包含”www”,如www.wrox.com 时,也是如此;

不能将这个属性设置为URL中不包含的域;

当页面中包含来自其他子域的框架或内嵌框架时,能够设置document.domain就非常方便了;

由于跨域安全限制, 来自不同子域的页面无法通过JavaScript通信;

而通过将每个页面的document.domain设置为相同的值,这些页面就可以互相访问对方包含的JavaScript对象了;

例如,假设有一个页面加载自www.wrox.com,其中包含一个内嵌框架,框架内的页面加载自p2p.wrox.com;

由于document.domain字符串不一样,内外两个页面之间无法相互访问对方的JavaScript对象;

但如果将这两个页面的document.domain值都设置为”wrox.com”,它们之间就可以通信了;

浏览器对domain属性还有一个限制,即如果域名一开始是”松散的”(loose);

那么不能将它再设置为”紧绷的”(tight);

换句话说,在将document.domain设置为”wrox.com”之后,就不能再将其设置回”p2p.wrox.com”,否则将会导致错误;

查找元素

getElementById()的ID在IE7及更早版本中可以不区分大小写;

如果页面中多个元素的ID值相同,getElementById()只返回文档中第一次出现的元素;

IE7及较低版本还为此方法添加了一个有意思的”怪癖”:

name特性与给定ID匹配的表单元素(<input>,<textarea>,<button><select>)也会被该方法返回;

如果有哪个表单元素的name特性等于指定的ID,

而且该元素在文档中位于带有给定ID的元素前面,那么IE就会返回那个表单元素;

例子;

<input type="text" name="myElement" value="Text field">
<div id="myElement">A div</div>
// IE7中调用document.getElementById("myElement"),返回input

getElementsByTagName()返回的也是一个动态集合,是一个HTMLCollection对象;

HTMLCollection对象有一个方法namedItem()可以通过元素的name特性获取集合中的项;

使用方括号语法可以实现同样的功能;

		// 假设有这样的元素
		<img src="myimage.gif" name="myImage">
		
		var images = document.getElementsByTagName("img");
		var myImage = images.namedItem("myImage");
		// 或
		var myImage = images["myImage"];

获取所有元素可传入*号;

var allElements = document.getElementsByTagName("*");

返回的所有元素按照在页面中出现的先后顺序排序;

IE不表演是不可能的,每个小节都要表演;

由于IE将注释(Comment)实现为元素(Element),因此在IE中调用getElementsByTagName(“*“)将会返回所有注释节点;

虽然标准规定标签名需要区分大小写,但为了最大限度地与既有HTML页面兼容;

传给getElementsByTagName()的标签名是不需要区分大小写的;

但对于XML页面而言(包括XHTML),getElementsByTagName()方法就会区分大小写;

HTMLDocument独有的方法getElementsByName();

getElementsByName()方法也会返回一个HTMLCollectioin;

但是,对于单选按钮来说,namedItem()方法则只会取得第一项(因为每一项的name特性都相同);

特殊集合

document对象的快捷方式:

1.document.anchors,包含文档中所有带name特性的<a>元素;

2.document.applets,包含文档中所有的<applet>元素,因为不再推荐使用<applet>元素,所以这个集合已经不建议使用了;

3.document.forms,包含文档中所有的<form>元素,与document.getElementsByTagName(“form”)得到的结果相同;

4.document.images,包含文档中所有的<img>元素,与document.getElementsByTagName(“img”)得到的结果相同;

5.document.links,包含文档中所有带href特性的<a>元素;

这个特殊集合始终都可以通过HTMLDocument对象访问到,

而且,与HTMLCollection 对象类似,集合中的项也会随着当前文档内容的更新而更新;

DOM一致性检测

检测浏览器实现了DOM的哪些部分;

document.implementation属性就是为此提供相应信息和功能的对象,与浏览器对DOM的实现直接对应;

var hasXmlDom = document.implementation.hasFeature("XML", "1.0");

但是,上有政策, 下有对策,浏览器可以自行决定是否与DOM规范保持一致;

Safari 2.x及更早版本会在没有完全实现某些DOM功能的情况下也返回true;

为此,我们建议多数情况下,在使用DOM的某些特殊的功能之前,最好除了检测hasFeature()之外,还同时使用能力检测;

文档写入

write(),writeln(),open(),close();

<script type="text/javascript">
	document.write("<strong>" + (new Date()).toString() + "</strong>");
</script>

脚本放哪儿就输出到哪儿;

当然可以用这种方式引入脚本;

<html>
<head>
    <title>document.write() Example 3</title>
</head>
<body>
    <script type="text/javascript">
        document.write("<script type=\"text/javascript\" src=\"file.js\">" +
            "<\/script>");
    </script>
</body>
</html>

如果在文档加载结束后再调用document.write(),那么输出的内容将会重写整个页面;

<html>
<head>
    <title>document.write() Example 4</title>
</head>
<body>
    <p>This is some content that you won't get to see because it will be overwritten.</p>
    <script type="text/javascript">
        window.onload = function(){
            document.write("Hello world!");
        };
    </script>
</body>
</html>

严格型XHTML文档不支持文档写入;对于那些按照application/xml+xhtml内容类型提供的页面,也同样无效;

ELement类型

Element节点的特征:

1.nodeType的值为1;

2.nodeName的值为元素的标签名;

3.nodeValue的值为null;

4.parentNode可能是Document或Element;

5.其子节点可能是Element,Text,Comment,ProcessingInstruction,CDATASection或EntityReference

nodeName与tagName两个属性返回相同的值,tagName从名字上更清晰;

在HTML中,标签名始终都以全部大写表示;

而在XML(有时候也包括XHTML)中,标签名则始终会与源代码中的保持一致;

也就是<div>的tagName是DIV;

HTML元素

每个HTML元素都有的标准特性:

1.id,元素在文档中的唯一标识符;

2.title,有关元素的附加说明信息,一般通过工具提示条显示出来;

3.lang,元素内容的语言代码,很少使用;

4.dir,语言的方向,值为”ltr”(left-to-right,从左至右)或”rtl”(right-to-left,从右至左),也很少使用;

5.className,与元素的class 特性对应,即为元素指定的CSS类;没有将这个属性命名为class,是因为class是ECMAScript的保留字;

保留字参见第一章,然后我去看了一下233没写笔记;

这五个都是可以被修改的,然后特地试了一下;

    $('#btn-second').click(function(){
       document.getElementById("sss").id = "ysy";
    });

    $('#sss').click(function() {
        console.log("click sss button");
    });

点击id为sss的按钮依然会console;但是该按钮的id已经变成了ysy;

取得特性

特性的名称是不区分大小写的,即”ID”和”id”代表的都是同一个特性;

getAttribute(),setAttribute(),removeAttribute();

根据HTML5规范,自定义特性应该加上data-前缀以便验证;

关于这点,idea这个ide一直对自定义属性报未知果然是因为前缀不是data-(

只有公认的(非自定义的)特性才会以属性的形式添加到DOM对象中;

IE:我不;

<div id="myDiv" align="left" my_special_attribute="hello!"></div>

alert(div.id); //"myDiv"
alert(div.my_special_attribute); //undefined(IE 除外)
alert(div.align); //"left"

有两个特殊的特性,其属性值与通过getAttribute()返回的值并不相同:style,onclick;

在通过getAttribute()访问时,返回的style特性值中包含的是CSS文本,而通过属性来访问它则会返回一个对象;

当在元素上使用时,onclick特性中包含的是JavaScript代码;

如果通过getAttribute()访问,则会返回相应代码的字符串;

而在访问onclick属性时,则会返回一个JavaScript函数;

如果未在元素中指定相应特性,则返回null;

这是因为onclick及其他事件处理程序属性本身就应该被赋予函数值;

基于这些差异,以及IE的再一次表演;

在IE7 及以前版本中,通过getAttribute()方法访问style特性或onclick这样的事件处理特性时,返回的值与属性的值相同;

开发人员只有在取得自定义特性值的情况下才会使用getAttribute()方法,大部分情况下都使用对象的属性;

设置特性

通过setAttribute()方法既可以操作HTML特性也可以操作自定义特性;

通过这个方法设置的特性名会被统一转换为小写形式,即”ID”最终会变成”id”;

removeAttribute(),这个方法用于彻底删除元素的特性;

调用这个方法不仅会清除特性的值,而且也会从元素中完全删除特性;

attributes属性

Element类型是使用attributes属性的唯一一个DOM节点类型;

attributes属性中包含一个NamedNodeMap,与NodeList类似,也是一个”动态”的集合;

元素的每一个特性都由一个Attr节点表示,每个节点都保存在NamedNodeMap对象中;

NamedNodeMap对象拥有下列方法:

1.getNamedItem(name):返回nodeName属性等于name的节点;

2.removeNamedItem(name):从列表中移除nodeName属性等于name的节点;

3.setNamedItem(node):向列表中添加节点,以节点的nodeName属性为索引;

4.item(pos):返回位于数字pos位置处的节点;


var id = element.attributes.getNamedItem("id").nodeValue;
// or
var id = element.attributes["id"].nodeValue;

element.attributes["id"].nodeValue = "someOtherId";

调用removeNamedItem()与removeAttribute()方法间唯一的区别是removeNamedItem()返回表示被删除特性的Attr节点;

创建元素

例子;

var div = document.createElement("div");
div.id = "myNewDiv";
div.className = "box";
document.body.appendChild(div);

// 在IE中还可以
var div = document.createElement("<div id=\"myNewDiv\" class=\"box\"></div >");

那么为什么IE可以这样呢,因为它用别的方式创建在IE7及更早版本中有问题啊233

其他浏览器均不支持该写法;

元素的子节点

元素可以有任意数目的子节点和后代节点,因为元素可以是其他元素的子节点;

不同浏览器在看待这些节点方面存在显著的不同;

例子:

<ul id="myList">
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
</ul >

如果是IE来解析这些代码,那么<ul>元素会有3个子节点,分别是3个<li>元素;

但如果是在其他浏览器中,<ul>元素都会有7个元素,包括3个<li>元素和4个文本节点;

表示<li>元素之间的空白符;

如果像下面这样将元素间的空白符删除,那么所有浏览器都会返回相同数目的子节点;

<ul id="myList"><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>

所以在遍历childNodes时要检查nodeType;

for (var i=0, len=element.childNodes.length; i < len; i++){
    if (element.childNodes[i].nodeType == 1){
    //执行某些操作
    }
}

还记得1是什么类型吗,是元素节点(

getElementsByTagName()也可以作为获得ul直接子节点li的方式,但是;

这里<ul>的后代中只包含直接子元素;

不过,如果它包含更多层次的后代元素,那么各个层次中包含的<li>元素也都会返回;

Text类型

文本节点,包含纯文本,不可以包含HTML代码,可以包含转义后的HTML字符;

特征:

1.nodeType 的值为3;

2.nodeName 的值为”#text”;

3.nodeValue 的值为节点所包含的文本;

4.parentNode 是一个Element;

5.不支持(没有)子节点;

可以通过nodeValue或data属性访问包含的文本;

appendData(text),deleteData(offset, count),insertData(offset, text),

replaceData(offset, count, text),splitText(offset),substringData(offset, count);

length,nodeValue.length,data.length一样;

从上面ul和li的例子可以看出来文本节点是什么了;

<!-- 没有内容,也就没有文本节点 -->
<div></div>
<!-- 有空格,因而有一个文本节点 -->
<div> </div>
<!-- 有内容,因而有一个文本节点 -->
<div>Hello World!</div>

在修改文本节点时还要注意,此时的字符串会经过HTML(或XML,取决于文档类型)编码;

//输出结果是"Some &lt;strong&gt;other&lt;/strong&gt; message"
div.firstChild.nodeValue = "Some <strong>other</strong> message";

创建文本节点

document.createTextNode();

一般情况下,每个元素只有一个文本子节点;

不过,在某些情况下也可能包含多个文本子节点;

如果两个文本节点是相邻的同胞节点,那么这两个节点中的文本就会连起来显示,中间不会有空格;

规范化文本节点

合并文本节点的方法normalize();

var element = document.createElement("div");
element.className = "message";
var textNode = document.createTextNode("Hello world!");
element.appendChild(textNode);
var anotherTextNode = document.createTextNode("Yippee!");
element.appendChild(anotherTextNode);
document.body.appendChild(element);
alert(element.childNodes.length); //2
element.normalize();
alert(element.childNodes.length); //1
alert(element.firstChild.nodeValue); // "Hello world!Yippee!"

浏览器在解析文档时永远不会创建相邻的文本节点;

这种情况只会作为执行DOM操作的结果出现;

分割文本节点

splitText();

var element = document.createElement("div");
element.className = "message";
var textNode = document.createTextNode("Hello world!");
element.appendChild(textNode);
document.body.appendChild(element);
var newNode = element.firstChild.splitText(5);
alert(element.firstChild.nodeValue); //"Hello"
alert(newNode.nodeValue); //" world!"
alert(element.childNodes.length); //2

分割文本节点是从文本节点中提取数据的一种常用DOM解析技术;

Comment类型

注释在DOM中是通过Comment 类型来表示的;

特征:

1.nodeType的值为8;

2.nodeName的值为”#comment”;

3.nodeValue的值是注释的内容;

4.parentNode可能是Document或Element;

5.不支持(没有)子节点;

Comment类型与Text类型继承自相同的基类;

因此它拥有除splitText()之外的所有字符串操作方法;

使用document.createComment()并为其传递注释文本也可以创建注释节点;

var comment = document.createComment("A comment ");

开发人员很少会创建和访问注释节点,因为注释节点对算法鲜有影响;

此外,浏览器也不会识别位于</html>标签后面的注释;

如果要访问注释节点,一定要保证它们是<html>元素的后代(即位于<html>和</html>之间);

CDATASection类型

CDATASection类型只针对基于XML的文档,表示的是CDATA区域;

与Comment 类似,CDATASection类型继承自Text类型,拥有除splitText()之外的所有字符串操作方法;

特征:

1.nodeType的值为4;

2.nodeName的值为”#cdata-section”;

3.nodeValue的值是CDATA 区域中的内容;

4.parentNode可能是Document 或Element;

5.不支持(没有)子节点;

DocumentType类型

不常用,包含文档的doctype有关的所有信息;

特征:

1.nodeType的值为10;

2.nodeName的值为doctype的名称;

3.nodeValue的值为null;

4.parentNode是Document;

5.不支持(没有)子节点;

三个属性name,entities 和notations;

name表示文档类型的名称;

entities是由文档类型描述的实体的NamedNodeMap对象;

notations是由文档类型描述的符号的NamedNodeMap对象;

浏览器中的文档使用的都是HTML或XHTML文档类型,

因而entities和notations都是空列表(列表中的项来自行内文档类型声明);

但不管怎样,只有name属性是有用的;

这个属性中保存的是文档类型的名称,也就是出现在<!DOCTYPE之后的文本;

例子:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
DocumentType 的name 属性中保存的就是"HTML":
alert(document.doctype.name); //"HTML"

然而HTML5已经没内容了2333

DocumentFragment类型

文档片段,这个类型没有对应的标记,但是可以包含和控制节点,可以说深藏功与名了;

特征:

1.nodeType的值为11;

2.nodeName的值为”#document-fragment”;

3.nodeValue的值为null;

4.parentNode的值为null;

5.子节点可以是Element,ProcessingInstruction,Comment,Text,CDATASection或EntityReference;

例子:


var fragment = document.createDocumentFragment();
var ul = document.getElementById("myList");
var li = null;
for (var i=0; i < 3; i++){
    li = document.createElement("li");
    li.appendChild(document.createTextNode("Item " + (i+1)));
    fragment.appendChild(li);
}
ul.appendChild(fragment);

如果逐个地添加列表项,将会导致浏览器反复渲染;

为避免这个问题,可以使用一个文档片段来保存创建的列表项,然后再一次性将它们添加到文档中;

看了一下jquery和bootstrap-table都用到了这个方法;

Attr类型

特性节点,元素的特性在DOM 中以Attr类型来表示;

在所有浏览器中(包括IE8),都可以访问Attr类型的构造函数和原型;

从技术角度讲,特性就是存在于元素的attributes属性中的节点;

特征:

1.nodeType的值为2;

2.nodeName的值是特性的名称;

3.nodeValue的值是特性的值;

4.parentNode的值为null;

5.在HTML中不支持(没有)子节点;

6.在XML中子节点可以是Text或EntityReference;

3个属性:name,value,specified;

specified还记得吧,可以区分是默认的还是自定义的;

例子:

var attr = document.createAttribute("align");
attr.value = "left";
element.setAttributeNode(attr);
alert(element.attributes["align"].value); //"left"
alert(element.getAttributeNode("align").value); //"left"
alert(element.getAttribute("align")); //"left"

实际上,使用getAttribute(),setAttribute()和removeAttribute()方法远比操作特性节点更为方便;

哦2333

目前最长的一节(

终于完了