JavaScript学习笔记:初识JavaScript的DOM

发布于 大漠

JavaScript知识一直都是自己的短板,近一年多来一直在致力于增加这方面的能力,也在W3cplus梳理了一些有关于自己学习JavaScript的笔记。加上最近学习Vue相关的技能,越发自己在JavaScript方面的能力还欠缺很多,所以这段时间一直在补习JavaScript中DOM相关的知识。希望对于初学者有所帮助。

什么是DOM

MDN上对DOM是这样描述的:

DOM(文档对象模型)是HTML和XML文档的编程接口。它提供了对文档的结构化的表述,并定义一种方式可以使从程序中对该结构进行访问,从而改变文档的结构、样式和内容。DOM将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。

简单地说,DOM是一套对文档的内容进行抽象和概念化的方法

文档对象模型针对的是一份文档,加上各个浏览器渲染Web页面的具体方法略有不同,那么相同的一份代码在不同的浏览器中便会有冲突不断。为了让DOM更具标准化,DOM也被纳入W3C标准。在W3C的标准中,DOM是独立于平台和语言的一种接口,它允许程序和脚本动态的访问更新文档的结构、样式和内容。也就有了后面的内容,即DOM的

DOM的地位

众所周知,对于一个Web页面或者Web应用程序,他由三部分组成:HTMLCSSJavaScript

如果把一个Web页比作一套房子,那么房子的格局就是我们所说的HTML,而房子的装修就是CSS,对于房子中的门怎么开,灯怎么操作就是JavaScript。而其中的JavaScript赋予了Web页面的行为,通过它可以与页面进行交互,实现页面的动画效果等等。也就是说,要实现页面的动态交互和效果,操作HTML才是核心。事实上操作HTML其实就是对DOM的操作。DOM给我们提供了用程序来动态控制HTML的接口,也就是早期的DHTML的概念。因此,DOM处在JavaScript赋予HTML具备动态交互和效果的能力的核心地位上

在Web中,JavaScript和DOM经常是作为一个整体出现,因为JavaScript通常都是用来进行DOM操作和交互的。

具体怎么操作和交互,我们放到后续来介绍。

DOM的发展史

Web中的DOM发展到目前为止经历了DOM0、DOM1、DOM2和DOM3几个版本。而每个版本都略有差异。

DOM0

JavaScript在早期版本中提供了查询和操作Web文档内容的API,比如图像和表单。而这个阶段的DOM实际上还未成为W3C标准的初级阶段。现在习惯上被称为DOM0

DOM1

在1998年10月份时,DOM成为W3C推荐标准。W3C将DOM定义为一个与平台和编程语言无关的接口,通过这个接口程序和脚本可以动态的访问和修改文档的内容、结构和样式。

DOM1主要定义了HTML和XML文档的底层结构。而且这个阶段的DOM由两个模块组成: DOM核心DOM HTML。其中, DOM核心规定了基于XML的文档结构标准,通过这个标准简化了对文档中任意部分的访问和操作。DOM HTML则在DOM核心的基础上加以扩展,添加了针对HTML的对象和方法,如JavaScript中的Document对象。

DOM2

DOM2在DOM1的基础上增强了更多的交互能力,也支持更高级的XML特性。DOM2将DOM分为更多具有联系的模块。DOM2级在原来的DOM基础上又扩充了鼠标、用户界面事件、范围、遍历等细分模块,而且通过对象接口增加了对CSS的支持。

在DOM2中引入了下列模块,在模块中包含了众多新类型和新接口:

  • DOM视图(DOM Views):定义了跟踪不同文档视图的接口
  • DOM事件(DOM Events):定义了事件和事件处理的接口
  • DOM样式(DOM Styles):定义了基于CSS为元素应用样式的接口
  • DOM遍历和范围(DOM Traversal and Range):定义了遍历和操作文档树的接口

完整的DOM2标准如下图所示:

DOM3

DOM3再一次的扩展了DOM,引入了以统一方式加载和保存文档的方法,它在DOM Load And Save这个模块中定义;同时新增了验证文档的方法,是在DOM Validation这个模块中定义的。在DOM3中引入了以下模块:

  • DOM加载和保存模块(DOM Load and Save):引入了以统一方式加载和保存文档的方法
  • DOM验证模块(DOM Validation):定义了验证文档的方法
  • DOM核心的扩展(DOM Styles):支持XML1.0规范,涉及到XML Infoset、XPath和XML Base

认识DOM

前面我们对DOM做了一些初步的介绍,大家或许对DOM的抽象概念有了一定的了解,但对于初学者而言,对于DOM的理解还只停留在理论与概念上,要说到具体的操作或者说灵活的控制DOM,还是无法做到的。那么接下来,我们以代码为例,结合DOM的一些概念来强化初学者对DOM的认识,同时也是为后面的内容做技术准备。

DOM中的O

通过前面的内容,我们知道DOM(Document Object Model)指的是文档对象模型。基中**D(Document)可以理解为整个Web加载的页面文档,O(Object)可以理解为类似window对象只读的东西,可以调用属性和方法,这里我们说的是document对象,M**(Model)可以理解为Web页面文档的树形结构。

这里我们主要说的是这个**O,也就是Object,即对象**。在JavaScript中,对象是这样的一个概念:

对象:就是由一些属性和方法组合在一起而构成的一个数据实体。

JavaScript中的对象主要可分为三种类型:

  • 用户定义对象(User-Defined Object):由程序员自行创建的对象
  • 内建对象(Native Object):内建在JavaScript语言里的对象,如ArrayMathDate
  • 宿主对象(Host Object):由浏览器提供的对象,如windowdocument

其中第三种宿主对象是我们要讨论的重点,这主要是因为JavaScript是一种解释型语言,所以必须依赖运行于一个宿主环境中,那么客户端JavaScript一般的宿主环境就是指浏览器window对象对应着浏览器窗口本身,这个对象的属性和方法通常统称为BOM(浏览器对象模型)。我们不需要与BOM打太多的交道,而是主要把精力集中于浏览器窗口中的Web页面内容上。document对象的主要功能就是处理Web页面内容。

DOM树

下面是具体理解DOM的一个关键了,DOM把一份文档表示为一棵树,这棵树可以理解成为类似于一个家族的族谱树,一般用parent(父)、child(子)和sibling(兄弟)等记号来表明家族成员之间的关系。那么,组成族谱树的基本单元是家族成员,组成DOM树的基本单元则是节点(node),也就是说,以后我们看到一份Web页面文档时,就把它当做一棵节点树。

那么DOM节点是什么?

DOM节点(即:Node)通常对应于一个标签、一个文本或者一个HTML属性。DOM节点有一个nodeType属性用来表示当前元素的类型。也就是说,DOM可以将任何HTML描绘成一个由多层节点构成的结构。DOM节点分为12种不同类型,每种类型分别表示文档中不同的信息及标记。每个节点都拥有各自的特点、数据和方法,也与其他节点存在某种关系。节点之间的关系构成了层次,而所有页面标记则表现为一个以特定节点为根节点的树形结构,也就是前面所说的DOM树。

比如,我们有这样的一个.html文档:

<!DOCTYPE html>
<html>
    <head>
        <title>DOM Tree Sample Document</title>
        <!-- inclue some CSS style sheet to make everything look a little nicer -->
        <link rel="stylesheet" type="text/css" href="../style/source.css" />
        <link rel="stylesheet" type="text/css" href="../style/chapter.css" />

        <!-- Your ADS library with the common JavaScript objects -->
        <script type="text/javascript" src="../js/base.js"></script>
        <!-- Log object from Chapter 2 -->
        <script type="text/javascript" src="../js/my.js"></script>
        <!-- Your testing file -->
        <script type="text/javascript" src="../js/dom.js"></script>


    </head>
    <body>
        <h1>DOM Tree</h1>
        <div id="content">
            <p>Examining the DOM2 Core and DOM2 HTML Recommendations</p>
            <h2>Browsers</h2>
            <p>Typically, you'll be expecting the following browsers:</p>
            <!-- Other browsers could be added but we'll keep the list 
            short for the example. -->
            <ul id="browserList">
                <li id="firefoxListItem">
                    <a href="http://www.getfirefox.com/"
                        title="Get Firefox" 
                        id="firefox">Mozilla Firefox</a>
                </li> 
                <li>
                    <a href="http://www.microsoft.com/windows/ie/downloads/" 
                        title="Get Microsoft Internet Explorer" 
                        id="msie">Microsoft Internet Explorer</a>
                </li> 
                <li>
                    <a href="http://www.apple.com/macosx/features/safari/" 
                        title="Check out Safari" 
                        id="safari">Apple Safari</a>
                </li>
                <li>
                    <a href="http://www.opera.com/download/" 
                        title="Get Opera" 
                        id="opera">Opera</a>
                </li> 
            </ul>
        </div>
    </body>
</html>

上面的HTML对应的DOM树形图如下:

浏览器解析上面的HTML时,会把标记解析为对象。文档中的每个标签都可以用一个核心对象来表示。如下图所示:

上图是按照W3C标准来解析的HTML文档。不过需要注意到标签间的空白,这些空白都被转换成了Text节点,这是DOM规范中对空白符和换行符转换的处理方式。之所以采取这种方式来处理,主要是希望DOM树能够反映文档中的所有信息。如果把标签之间的空白去掉的话,W3C的DOM2核心就不会再出现额外的Text节点,最终解析出来的DOM树如下图所示:

正如上图所示,上面的DOM树形图并无法展示对象之间的继承关系。当浏览器解析完HTML文档后,每个节点并非只是一个单纯的Element对象,而是继承了很多属性和方法。Element对象继承了Node对象的所有属性和方法。比如上面代码中的<a>标签,该标签是一个DOM2,HTML规范中的HTMLAnchorElement对象,继承关系如下图所示:

继承是面向对象语言中的一个重要组成部分,通过继承可以在各种对象之间维护共用的功能。继承也解释了为什么段落<p>和链接<a>元素都是Element对象,但在最终文档的DOM对象中,却存在由DOM2的HTMLParagraphElement对象和HTMLAnchorElement对象规定的不同属性。

是不是感觉好深奥,不用担心,随着后续的内容,我们会越来越理解这些。灵活的掌握这些知识点。

DOM节点类型

DOM1定义了一个Node接口,这个Node接口在JavaScript中是作为Node类型来实现的。除了IE浏览器之外的浏览器都可以访问这个类型。每个节点都有一个nodeType属性,用于表明节点的类型。节点类型通过定义数值常量字符常量两种方式来表示,IE只支持数值常量

DOM的节点类型共有12种,这里介绍常用的七种类型,如下表所示:

节点类型 数值常量 字符常量
Element(元素节点) 1 ELEMENT_NODE
Attr(属性节点) 2 ATTRIBUTE_NODE
Text(文本节点) 3 TEXT_NODE
Comment(注释节点) 8 COMMENT_NODE
Document(文档类型节点) 9 DOCUMENT_NODE
DocumentType(文档类型节点) 10 DOCUMENT_TYPE_NODE
DocumentFragment(文档片段节点) 11 DOCUMENT_FRAGMENT_NODE

而其中元素节点文本节点属性节点是我们操作DOM最常见的几种节点类型。具体怎么操作,这篇文章将不会涉及,我们还是简单的了解一下对应的Node类型是些什么。

元素节点:Element

元素节点是组成文档树的重要部分,它表示了HTML、XML文档中的元素。通常元素因为有子元素、文本节点或者两者的结合,元素节点是唯一能够拥有属性的节点类型。

比如上面示例代码中的htmlheadtitlebodydivulli等等都是属于Element(元素节点)。

属性节点:Attr

属性节点代表了元素中的属性,因为属性实际上是附属于元素的,因此属性节点不能被看做是元素的子节点。因而在DOM中属性没有被认为是文档树的一部分。也就是说,属性节点其实被看做是包含它的元素节点的一部分,它并不作为单独的一个节点在文档中出现。

比如我们常在HTML元素中看到的一些属性,正如上例中的idclasshref等都属于Attr(属性节点)。

文本节点:Text

文本节点是只包含文本内容的节点,在XML中称为字符数据,它可以由更多的信息组成,也可以只包含空白。在文档树中元素的文本内容和属性的文本内容都是由文本节点来表示的。

比如上例中的:DOM Tree Sample DocumentMozilla Firefox之类的都是属于Text(文本节点)。

注释节点:Comment

注解节点其实就是我们平时所说的注释内容。比如,例子中像这样的<!-- Your testing file -->都属于Comment(注释节点)。

文档节点:Document

文档节点是文档树的根节点,它是文档中其他所有节点的父节点。要注意的是,文档节点并不是HTML、XML文档的根元素,因为在XML文档中,处理指令、注释等内容可以出现在根元素之外,所以在构造DOM树的时候,根元素并不适合作为根节点,因此就有了文档节点,而根元素是作为文档节点的子节点出现的。

比如例子中的<! DOCTYPE html>html作为Document(文档节点)的子节点出现。

文档类型节点:DocumentType

每个Document都有一个DocumentType属性,它的值或是null,或者是DocumentType对象。比如声明文档类型时<! DOCTYPE html>就是文档类型节点。

文档片段节点:DocumentFragment

文档片段节点是轻量级的或最小的Document对象,它表示文档的一部分或者是一段,不属于文档树。不过它有一种特殊的行为,该行为使得它非常有用。比如,当请求把一个DocumentFragment节点插入到文档的时候,插入的不是DocumentFragment自身,而是它的所有的子孙节点。这使得DocumentFragment成了有用的占位符,暂时存放那些一次插入文档的节点,同时它还有利于实现文档的剪切、复制和粘贴等操作。

DOM节点信息

在JavaScript中使用nodeType可以获取每个节点的类型;对于节为的相关的信息,可以通过nodeNamenodeValue来。不过这两个属性取决于节点的类型。所以在使用nodeNamenodeValue之前最好能先使用nodeType对节点类型做一下检测。如果节点是一个元素,nodeName中保存的始终是元素的标签名,而nodeValue值始终为0

DOM节点关系

每个节点都有一个childNodes属性,其中保存着一个NodeList对象。NodeList对象是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点。比如下图:

NdoeList对象的特殊之处在于,它实际上是基于DOM结构动态执行查询的结果,因此DOM的变化能直接反映在NodeList对象之中。它是有生命的对象,而不是在我们第一次访问它在某一个瞬间拍下的快照。

上图展示了DOM节点之间的关系,事实上,JavaScript也提供了一些方法,可以操作DOM节点,也可以改变他们之间的关系。对于如何操作DOM节点,这里不做过多阐述,在后续的内容中,我们会详细看看DOM节点是怎么操作的。

总结

这是有关于JavaScript中DOM的知识的第一篇文章,这篇文章主要介绍了一些有关于DOM方面最基础的东西。比如DOM的概念、发展历程、地位、类型等。但对于初学者而言,这些东西或许会感觉太空洞了,毕竟没有代码那样来得实际。因为纯概念的东西,太过于抽象,难于理解,但不用担心,后面的内容,我们会接触到DOM相关的操作,特别是有关于DOM的等。感兴趣的同学,欢迎持续关注相关的更新。

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《图解CSS3:核心技术与案例实战》。

如需转载,烦请注明出处:https://www.fedev.cn/javascript/intro-dom.htmlNike Fingertrap Air Max