JavaScript中的DOM

文档对象模型(DOM)

什么是DOM?DOM是一种接口(API),利用这个接口我们可以方便地操作HTML和XML页面。
这个接口将HTML或者XML页面看成一个由多个层次节点构成的结构,文档是由一个个节点组成的。也就是说DOM的核心就是节点。
每个节点都有自己的属性和方法,节点之间存在关系,这种关系就构成了层次。所有的页面标记表现为以某个节点为根节点的树形结构。

节点类型

文档中存在许许多多的节点,这些节点分别属于各种各样的类型。
总共有12中类型的节点,但不是所有的都很常用。这12种类型的节点都继承自一个基本的类型节点:Node类型。
如何区分这12种类型的节点呢?每个节点都有一个nodeType属性来标志自己是什么类型的节点。nodeType为1则是元素节点Element类型,为3则是文本节点Text类型等等。利用这个属性我们就可以得知节点的类型。
不同的节点类型有不同的属性和方法,也有一些共有的属性和方法。接下来就是一个常用的节点类型。

Node类型

首先是最基本的Node类型,这可以看作是所有类型节点的共性,因为他们都是继承这个基本节点类型而来的。
1.nodeName和nodeValue属性
不同类型的节点这两个属性的值不同,因类型而异。如元素类型的nodeName则为元素的标签名,nodeValue值为null。

2.节点关系
节点之间不是独立存在的,他们之间有着这样或那样的联系。基本的关系有父子、同胞。不仅存在这些关系,而且DOM也为我们提供了可以利用这些关系的接口。最常用的每个节点都有一个childNodes属性,其指向一个NodeList对象。这个对象像数组一样有序保存着该节点的所有直接子节点。但是它有些特殊,它是一个“动态”的数组,这是说当该节点的子节点发生变化时,这个数组会自动跟着变化,它是动态查询的结果,不是一成不变的。
利用childNodes属性可以得到子节点的NodeList,然后我们就可以通过这个NodeList来访问子节点了,可以用下标像数组一样访问,也可以用item(index)方法来访问。
另外每个节点都有的一个属性是parentNode,指向该节点的父节点。还有nextSibling和previousSibling属性,指向该节点的后一个或前一个同胞节点,如果不存在则属性值为null。同时每个父节点也有firstChild和lastChild属性,指向子节点NodeList的第一项和最后一项,也有一个hasChildNodes()方法来判断是否有子节点。
最后所有节点共有的一个属性是ownerDocument,指向可以表示这个节点所在文档的文档节点。

我们可以看到,节点的大多数共有的属性都是用来表征节点之间的关系的。

3.操作节点的方法。
DOM不仅定义了节点的属性,也提供了操作节点的方法。
首先是appendChild()最常用,可以在childNodes列表末尾追加一个节点。
然后是insertBefore(),在childNodes列表指定节点之前插入一个节点。
还有就是replaceChild()、removeChild()等方法。
这些方法我们可以看到都是改变节点的childNodes列表。

4.再有就是cloneNode()方法和 normalize()方法了。cloneNode()就是创建一个节点的副本,不过不会复制节点上已有的事件处理程序等其他JavaScript属性。normalize()方法唯一的作用是处理文本节点。

Document类型

一个节点是Document类型的节点则说明这个节点表示一个文档。
我们常用的document对象就是HTMLDocument的一个实例,而HTMLDocument就是继承自Document类型。document的含义就是代表整个html文档。
属性:
document.documentElement 指向<html>元素和document.firstChild及document.childNodes[0]指向相同;
document.body 指向<body>元素;
document.title指向<title>元素;
document.URL 页面的url
document.domain 页面的域名
document.referrer 链接到当前页面的页面url

方法:
document.getElementById();
document.getElementsByTagName();
document.write();
要注意的是getElementsByTagName(),该函数会返回一个HTMLCollection对象,这是一个和NodeList类似的一个“动态”集合。除了可以用下标和item()方访问集合内的元素外,还可以通过namedItem()和按名称访问项。

一些特殊集合:
document.forms
document.anchors

Element类型

属性:
tagName,与nodeName相同返回标签名
id
title
className因为class是保留字
lang
dir语言的方向值为ltr或rtl
方法:
每个元素都有一个或多个特性,用来提供元素的附加信息。如id,class,align,onclick等等。DOM提供了操作这些特性的方法
getAttribute();
setAttribute();
removeAttribute();
除了用以上操作元素特性的方法,DOM还提供了attributes属性来直接获得元素的所有特性,attributes属性包含一个NamedNodeMap,这也是一个“动态”集合。每个特性都是集合中的一个Attr节点。集合有以下方法来操作这些属性:
getNamedItem();
removeNamedItem();
setNamedItem();
item();
一般来说我们不怎么用attributes属性,因为getAttribute()等方法就能满足我们的需求,但是在遍历元素所有特性的时候就用到attributes属性了。

创建元素节点:document.createElement();

Text类型

属性:
data与nodeValue相同,包含节点中的文本
方法:
appendData();
deleteData();
insertData();
replaceData();
splitText();
substringData();
当元素包含多个文本节点时,可以使用normalize()方法将多个文本节点合并成一个。

创建文本节点:document.createTextNode();

DocumentFragment类型

文档片段类型,作用是当我们要往文档中增加多个节点时,一个一个增加则会导致每次增加完成文档都要重新渲染一次,我们就可以先将要增加的节点放在文档片段中,再一次性将文档片段加入到文档中。

操作表格

当我们想向表格中增加节点时一次次调用createElement()和appendChild()很麻烦,DOM为我们提供了可以更加方便地操作表格的方法
tbody.insertRow(pos);
tbody.rows[pos];
rows[pos].insertCell(pos);
rows[pos].cells[pos];

理解“动态”集合

NodeList、HTMLCollection、NamedNodeMap都是动态集合。也就是文档发生变化时集合内容也会跟着变。其实他们本质上都是动态查询文档的结果,也就是我们每次访问这些集合时都会查询一遍文档来得到这些集合。而这些查询肯定是特别消耗性能的,所以我们应该尽量避免访问这些集合。
下面的例子会导致无限循环:

var divs = document.getElementsByTagName("div");
var i, div;

for (i = 0; i < divs.length; i++) {
    div = document.createElement("div");
    document.body.appendChild(div);
}

我们的divs.length并不是不变的,每次我们访问这个属性就会去查询文档中所有的div来得到这个属性值,每次文档中都会增加一个div,也就是divs.length会一直增加导致无限循环。
要解决这个问题我们只需要在循环开始前将divs.length赋值给另一个变量即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值