您的位置:首页 > Web前端 > Node.js

DOM(文档对象模型)

2014-05-12 16:11 471 查看

节点层次

DOM可以将任何html或xml文档描绘成一个由多层节点构成的结构。

<html>
<head>
<title>文档</title>
</head>
<body>
<p>Hello World!</p>
</body>
</html>

这样的一个结构,可以用下面的树形图来表示:



Node类型

javascript中所有节点都继承自Node类型,所有节点类型都共享着相同的基本属性和方法。

每个节点都有一个nodeType属性,用于表明节点类型,可用以下12个数值常量来表示:

nodeType等价命名常量
1Node.ELEMENT_NODE
2Node.ATTRIBUTE_NODE
3Node.TEXT_NODE
4Node.CDATA_SECTION_NODE
5Node.ENTITY_REGERENCE_NODE
6Node.ENTITY_NODE
7Node.PROCESSIONG_INSTRUCTION_NODE
8Node.COMMENT_NODE
9Node.DOCUMENT_NODE
10Node.DOCUMENT_TYPE_NODE
11Node.DOCUMENT_FRAGMENT_NODE
12Node.NOTATION_NODE
其中比较重要的是:1(元素)、2(属性)、3(文本)、8(注释)、9(文档)。

注意:IE中没有公开Node类型的构造函数,所以使用常量不能跨浏览器兼容,所以建议如需试用,建议试用数值值来进行操作。

如判断一个节点是否是元素:

if(someNode.nodeType==1){
//code
}

Node类型还定义了所有节点类型都包含的特性和方法:

特性/方法类型/返回类型说明
nodeNameString节点的名字。返回值取决于节点类型。
nodeValueString节点的值。返回值取决于节点类型。
nodeTypeNumber节点类型
childNodesNodeList保存子节点的类数组对象。能够实时反映DOM结构的变化。
parentNodeNode元素的父节点。
previousSiblingNode指向前一个兄弟节点,如果该节点是第一个节点,则为null。
nextSiblingNode指向后一个兄弟节点,如果该节点是最后一个节点,则为null。
firstChildNode指向childNodes返回的列表中的第一个节点。
lastChildNode指向childNodes返回的列表中的最后一个节点。
hasChildNodes()Boolean当节点包含一个或多个子节点时,返回true。
ownerDocumentDocument表示整个文档的文档节点。
appendChild(node)Node将node添加到childNodes列表末尾,返回新增节点。如果是文档中已有的节点,则将该节点移到新的位置。
insertBefore(newnode,refnode)Node在特定的位置(即参照节点refnode)前插入新的节点(newnode)。返回新插入的节点。
replaceChild(newnode,oldnode)Node用新节点(newnode)替换旧节点(oldnode)。返回旧节点。此时旧节点其实仍然在文档中,只是没了自己的位置。
removeChild(node)Node移除节点。返回被移除的节点。同样,被移除的节点任然在文档中,只是没了自己的位置。
cloneNode()Node用于复制节点。当传人参数true时,将复制该节点及其整个子节点树;当传人参数为false时,只复制该节点本身。返回被复制的节点。

Document类型

nodeType:9
nodeName:'#document'
nodeValue:null
parentNode:null
ownerDocument:null

文档的子节点

属性说明浏览器支持情况
document.documentElement指向<html>元素所有浏览器都支持
document.body指向<body>元素所有浏览器都支持
document.doctype取得对<!DOCTYPE>的支持IE8:如果存在文档类型声明,值始终为null;

IE9+及Firefox:如果存在文档类型声明,会将其作为文档的第一个子节点,与document.firstChild值一样;

Safari/Chrome和Opera:如果存在文档类型声明,会解析,但不作为子节点,不会出现在document.childNodes中。

文档信息

属性说明
document.title包含<title>元素中的文本。读:document.title;写:document.title='...'。
document.URL包含页面完整的URL。只读。
document.domain包含页面的域名。可读写。
document.referrer保存着链接到当前页面的那个页面的URL,在没有源页面的情况下,可能包含空字符串。只读。
注意:

1.domain虽然可以设置,但也不是可以设置任何值。如果URL中包含一个子域名,如p2p.wez.com,那么domain就只能设置为‘wez.com’。不能设置为URL中不包含的域。

2.如果域名一开始是‘松散的’,那么就不能将它再设置为‘紧绷的’。即,在将document.domain设置为‘wez.com’后,就不能再将其设置为‘p2p.wez.com’了。

查找元素

document.getElementById(id):获得传入id所对应的元素,若没有对应元素,返回null。注意,避免让表单字段的name特性与其他元素的id相同。

document.getElementsByTagName(tagname):返回传入的标签名所对应包含0个或多个元素的列表。这是一个动态集合,可用[]或item()访问。

document.getElementsByName(name):返回给定name的所有元素。

文档写入

document.write()和document.writeln()两个都是写入,前者原样写入,后者会在字符串末尾添加换行符。

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

Element类型

nodeType:1
nodeName:元素标签名
nodeValue:null
parentNode:Document或Element
tagName:元素标签名,大写

HTML元素

每个html元素都存在以下特性:

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

title,有关元素的说明信息;

lang,元素内容语言代码,很少用;

dir,语言方向,值为ltr(从左至右)或rtl(从右至左),也很少用;

className,为元素指定的css类。

这些属性都是可读写的。如,div.id='div1';id=div.id。

取得特性

node.getAttribute(attr),用于取得元素特性的值,如果特性不存在,则返回null。传入的特性可以是自定义特性。

注意:

1.传递给getAttribute()的特性名要与实际的特性名相同。不过,特性名称是不区分大小写的。

2.建议自定义特性名称应该加上data-前缀,以便验证。

任何元素的非自定义特性,也都可以通过元素本身来访问。如,div.id。

通常使用属性来访问非自定义属性,而使用getAtrribute()来访问自定义属性。

设置特性

setAttribute()方法用于设置元素属性。它接受两个参数,要设定的特性名和值。如果属性存在,会以新的值替换旧的值;如果属性不存在,则创建属性并设置其值。

这个方法可以操作html特性也可以操作自定义特性。通过该方法设置的特性名会统一转换为小写形式。

删除特性

removeAttribute(),用于彻底删除元素特性。该方法不仅清除特性值,而且也会从元素中完全删除特性。

这个方法不常用。

attributes属性

只有element类型才有attributes属性。它包含一个NamedNodeMap对象,是一个动态的Attr节点对象。

attributes属性中包含的所有节点的nodeName就是特性名称;nodeValue就是特性值

NamedNodeMap对象有以下方法:

getNamedItem(name):获得元素特性,传人的参数为特性名。

//获取特性:
var id=element.attributes.getNamedItem('id').nodeValue;
//或
var id=element.attributes['id'].nodeValue;

//设置特性:
element.attributes['id'].nodeValue='someOhterId';


removeNamedItem(name):移除特性,传入的name为特性名。该方法与在元素上调用removeAttribute()方法效果相同,直接删除给定名称的特性,并返回。

var oldAttr=elememt.attributes.removeNamedItem('id');


setNamedItem(node):为元素添加新特性,传人的参数为新特性节点,该方法很少用。

element.attributes.setNamedItem(newAttr);


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

创建元素

document.createElement()方法用于创建新元素。接受一个参数,为要创建元素的标签名,不区分大小写。

//创建一个新的div,并为其添加id,样式等属性,最后添加到文档末尾
var div=document.createElement('div');
div.id='newDiv';
div.className='box';
document.body.appendChild(div);
元素的子节点

元素的childNodes中包含了元素的所有子节点。

不同浏览器看待元素的子节点有不同的标准,所以,在利用元素子节点来执行某些操作前,要先检查nodeType属性。

for(var i=0,len=element.childNodes.length; i<len;i++){
if(element.childNodes[i].nodeType==1){
//code..
}
}


Text类型

nodeType:3
nodeName:‘#text’
nodeValue:节点所包含的文本
parentNode:一个Element
没有子节点
以下方法可操作节点中的文本:

appendData(text):将text添加到文本节点末尾;

deleteData(offset,count):在offset指定的位置开始删除count个字符;

insertData(offset,text):在offset指定的位置插入text;

replaceData(offset,count,text):用text替换从offset指定的位置开始到offset+count为止处的文本;

splitText(offset):从offset指定的位置将当前文本节点分寸两个文本节点;

substringData(offset,count):提取从offset指定的位置开始到offset+count位置处的字符串;

data.length/nodeValue.length:节点中字符的数目;

创建文本节点

document.createTextNode(text)方法用于创建文本节点。text为要插入节点中的文本。

var element=document.createElement('div');
elememt.className='message';

var textNode=document.createTextNode('Hello world!');
element.appendChild(textNode);

document.body.appendChild(element);
上面的代码,创建了一个div,并且设置它的样式为‘message’,接着又创建了一个文本节点,将其添加到刚创建的div中,最后将这个div元素添加到body中。

规范化文本节点

normalize()方法用于规范文本节点,即加入在一个包含两个或多个文本节点的父元素上调用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);

alert(element.childNodes.length); //2

element.normalize();

alert(element.childNodes.length); //1
alert(element.firstChild.nodeValue); //Hello world!Yippee!
注意,浏览器在解析文档的时候永远不会出现创建相邻的文本节点,这种情况只会作为执行DOM操作的结果出现。

分割文本节点

splitText(pos)方法用于拆分一个文本节点为两个文本节点。\

这个方法按照pos指定的位置拆分节点,拆分后,原文本节点将包含从开始到指定位置之前的内容,而新文本节点将包含剩下的内容。返回的是新产生的文本节点,该节点与原节点的parentNode相同。

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


Comment类型

nodeType:8
nodeName:‘#comment’
nodeValue:注释内容
parentNode:Document或element
没有子节点

Comment类型与Text继承自相同的基类。它拥有除splitText()之外所有字符串操作方法。

使用document.createComment()并传人注释文本,可以用了创建注释节点。

CDATASection类型

nodeType:4
nodeName:‘#cdata-section’
nodeValue:CDATA区域中的内容
parentNode:Document或element
没有子节点

DocumentType类型

nodeType:10
nodeName:doctype的名称
nodeValue:null
parentNode:Document
没有子节点

DocumentFragment类型

nodeType:11
nodeName:‘#document-frament’
nodeValue:null
parentNode:null

DOM规定文档片段(document fragment)是一种‘轻量级’的文档,可以包含和控制节点,但不会像完整的文档那样占用额外的资源。在对DOM进行操作时,可以有效的减少资源占用。

创建文档片段

document.createDocumentFragment()方法可用来创建文档片段。

<ul id="myList"></ul>
<script type="text/javascript">
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);
</script>


Attr类型

nodeType:11
nodeName:特性名称
nodeValue:特性值
parentNode:null
没有子节点

Attr对象有三个属性:

name,是特性的名称,与nodeName的值相同;

value,特性的值,与nodeValue值相同;

specified,是一个布尔值,用以区别特性是在代码中指定的,还是默认的。

用document.createAttribute()传人特性名称可以穿件新特性节点。

不过通常都使用getAttribute()、setAttribute()和removeAttribute()来操作特性。

DOM操作技术

动态脚本

可以使用document.createElement()方法来创建外部引用脚本。

var script=document.createElement('script');
script.type='text/javascript';
script.src='client.js';
document.body.appendChild(script);

也可以结合使用document.createTextNode()来创建嵌入式脚本。

动态样式

可以使用document.createElement()方法来创建外部引用脚本。

var linkstyle=document.createElement('link');
linkstyle.rel='stylesheet';
linkstyle.type='text/css';
linkstyle.href='style.css';
var head=document.getElementsByTagName('head')[0];
head.appendChild(linkstyle);

同样也可以结合使用document.createTextNode()来创建嵌入式css。

操作表格

table元素属性方法:

属性/方法说明
caption保存着对<caption>元素(如果有)的指针
tBodies是一个<tbody>元素的HTMLCollection
tFoot保存着对<tfoot>元素(如果有)的指针
tHead保存着对<thead>元素(如果有)的制作
rows是一个表格中所有行的HTMLCollection
createTHead()创建<thead>元素,将其放到表格中,并返回引用
createTFoot()创建<tfoot>元素,将其放到表格中,并返回引用
createCaption()创建<caption>元素,将其放到表格中,并返回引用
deleteTHead()删除<thead>元素
deleteTFoot()删除<tfoot>元素
deleteCaption()删除<caption>元素
deleteRow(pos)删除指定位置的行
insertRow(pos)向rows集合中的指定位置插入一行
tbody元素属性方法:

属性/方法说明
rows是一个<tbody>中所有行的HTMLCollection
deleteRow(pos)删除指定位置的行
insertRow(pos)向rows集合中的指定位置插入一行,返回对新插入行的引用
tr元素属性方法:

属性/方法说明
cells保存着<tr>元素中单元格的HTMLCollection
deleteCell(pos)删除指定位置的单元格
insertCell(pos)向cells集合中的指定位置插入一个单元格,返回对新插入单元格的引用

使用NodeList

NodeList、NameNodeMap和HTMLCollection,都是动态的,即,当文档结构发生变化时,它们都会得到及时更新。

因此,要尽量减少访问NodeList的次数。因为梅此访问NodeList,都会运行一次基于文档的查询。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息