JS中的DOM简介

DOM是什么

  1. DOM是document object model的缩写,中文直译为文档对象模型。DOM提供了一系列的方案,其作用是用对象描述文档
  2. 需要指出的是,DOM是一个规范,而不是某个特定的编程语言的实现。所以不仅是js有DOM,任何一种语言都可以实现DOM的规范。但是在js中DOM的作用举足轻重,甚至可以说日常的开发基本都和DOM有关。
  3. DOM基本可以分为四部分,分别是DOM CoreDOM HTMLDOM StyleDOM Event

DOM树

对于HTML文件来说,DOM可以将其内容转化为一棵树,HTML文档中的标签、标签的属性、标签的样式等都可以转化为树的某个节点。这棵树就是DOM树。下面我们来看看他们是怎么转化的。
对于下面所示的HTML文件:

<!doctype html>
<html>
<head>
  <title>演示</title>
</head>
<body>
  <h1>演示的HTML</h1>
  <p>这是一个用于演示<strong>DOM树</strong>的HTML文档</p>
</body>
</html>

除却第一行的文档声明,如果我们把每一个html元素都看作树的一个节点,那么这个html文档生成的树会是下面这样:

这里写图片描述

对于树结构这里不做过多介绍,不理解的还请查阅相关资料。
从html元素的角度来说,<head><body>元素是嵌套在<html>元素内的,用树的数据结构用语来说:
- <html>节点是<head><body>节点的父节点
- <head><body>节点是<html>节点的子节点
- <head><body>节点的兄弟节点,反之亦然
对于剩余的节点,我们也可以用这样的关系描述出来
- <head>节点是<title>节点的父节点
- <title>节点是<head>节点的子节点
- <title>节点没有兄弟节点

这里比较有意思的问题是关于文本的问题。在DOM树中,文本也会作为节点解析。因此我们看到,<title>节点下还有子节点,这个子节点就是<title>元素中的内容。而在<p>标签中,由于存在一个<strong>标签,本来连贯的文本被分为三部分,<p>节点因而存在了三个子节点。
除此之外,对于位置最高的节点,我们一般称它为根节点。显而易见,html文档的根节点一般都是<html>

通过DOM树找到节点

现在我们可以用这些描述来表示这些节点的关系,但是这有什么作用呢?
首先,我们要先认识一个方法

document.getElementsByTagName("tagName")

这个方法需要传入一个字符串参数,表示要获取得标签的名称。这个方法可以从html文档中查找到标签名与给定的标签名相同的标签。也就是说,如果我这样用:document.getElementsByTagName("p"),那么它就会返回找到的<p>标签。由于<p>标签在html文档中出现的次数可能不止一次,所以这个方法会返回一个节点列表,列表中包含了所有从文档中找到的<p>标签,对于节点列表我们可以像数组一样访问其中的元素。即使文档中只有一个<p>标签,它也会返回一个只有一个元素的数组。
那么对于上面的html文档,如果我们想获取<body>标签,我们可以这样使用

var bodyNode = document.getElementsByTagName("body")[0];

现在,通过bodyNode变量就可以操作<body>节点了。
获得这个节点之后,我们就可以通过DOM树来获取与它有关系的节点。
我们来看下面的一些属性:

node.parentNode;      // 获取节点的父节点
node.firstChild;      // 获取节点的第一个子节点
node.lastChild;       // 获取节点的最后一个子节点
node.previousSibling; // 获取节点的前一个兄弟节点
node.nextSibling;     // 获取节点的后一个兄弟节点

这里的node是指通过上面讲过的document.getElementsByTagName()或其他作用相似的方法获取到的任何html文档的节点。
而通过上面列举的一些属性,我们可以根据节点之间的关系轻松的获取与之“关系密切”的节点。

比如我们想要获取根节点<html>,由于此根节点也是<body>节点的父节点,我们可以这样获取:

// 获取根节点<html>
var htmlNode = bodyNode.parentNode;

如果我们想获取<h1>节点,我们可以想到如下方法:

// 获取<h1>节点
var h1Node = bodyNode.firstChild;

但实际上,这样做是错误的,通过上面的语句我们无法获取h1节点。这是因为我们上面讲过:文本也会被解析成为节点。而<body><h1>标并不是紧紧相邻的,它们中间有一个空行而且还有缩进:

这里写图片描述

即图中红色所标注的位置,这些空白字符导致了我们不能通过bodyNode.firstChild获取我们想要的<h1>节点。同样的,我们通过其他的属性,比如node.lastChildnode.previousSiblingnode.nextSibling也不会获得我们希望获得的html元素节点,可能只是一些空白文本。

但是在html文档的编写中,换行和缩进是必不可少的,它们使得html文档结构更加清晰。那么,我们能否在不改变文档结构的前提下,忽略这些空白文本带来的影响呢?
下面是一些可能更为有用的属性:

node.firstElementChild;      // 获取节点的第一个html元素子节点
node.lastElementChild;       // 获取节点的最后一个html元素子节点
node.previousElementSibling; // 获取节点的前一个html元素兄弟节点
node.nextElementSibling;     // 获取节点的后一个html元素兄弟节点

通过使用这些属性,就可以达到我们想要的效果了~

// 获取<h1>节点
var h1Node = bodyNode.firstElementChild;
// 获取<p>节点
var pNode = bodyNode.lastElementChild;
// 获取<head>节点
var headNode = bodyNode.previousElementSibling;

下面我们再来考虑:如何通过<body>节点获取<strong>节点呢?
我们可以看到,<strong>节点是<p>节点的第一个html元素子节点,而<p>节点是<body>节点的最后一个html元素子节点,所以我们可以这样获取:

// 获取<strong>节点
var strongNode = bodyNode.lastElementChild.firstElementChild;

最后,我们再来介绍两个属性:

node.childNodes; //获取节点的所有子节点
node.children;   //获取节点的所有html元素子节点

当某个元素的子节点比较多(很经常)的情况下,这个属性为我们找到某个子元素提供了方便。childNodes返回一个节点列表,包括了所有的子节点,我们可以像操作数组一样操作它。比如我们想获取第一个节点就可以这样childNodes[0],事实上它和firstChild返回的结果是一样的。获取第n个子节点,就可以使用childNodes[n]。如果我们想获取子节点的个数,可以使用childNodes.length
children的用法与childNodes相同,只不过获取的是所有html元素子节点,这个属性会忽略文本子节点。

总结

  1. DOM是文档对象模型,是一种规范,其作用是用对象描述文档。DOM在js中有举足轻重的作用。
  2. DOM将文档转化为树形结构,叫做DOM树。对于HTML文档,HTML元素和文本都会被转化为树的节点。
  3. 通过document.getElementsByTagName()方法可以从文档中获取对应的html元素列表,我们可以像数组一样操作这个列表获取对应的html元素。
  4. DOM提供了两组属性用来获取与节点有关系的其他节点。
    1) 第一组会获取包括文本节点在内的所有节点
node.parentNode;      // 获取节点的父节点
node.firstChild;      // 获取节点的第一个子节点
node.lastChild;       // 获取节点的最后一个子节点
node.previousSibling; // 获取节点的前一个兄弟节点
node.nextSibling;     // 获取节点的后一个兄弟节点
node.childNodes;      // 获取节点的所有子节点
2) 第二组只会获取有关联的HTML元素节点
node.firstElementChild;      // 获取节点的第一个html元素子节点
node.lastElementChild;       // 获取节点的最后一个html元素子节点
node.previousElementSibling; // 获取节点的前一个html元素兄弟节点
node.nextElementSibling;     // 获取节点的后一个html元素兄弟节点
node.children;               // 获取节点的所有html元素子节点
*在通过DOM树根据节点关系获取节点时,要注意空白节点的问题。*
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值