美文网首页饥人谷技术博客
JavaScript 中的 文档对象模型DOM

JavaScript 中的 文档对象模型DOM

作者: EnochQin | 来源:发表于2018-06-18 13:55 被阅读3次

    前言:在JavaScript中,DOM操作虽然公认的不好用,但它是最基础的,那么就让我们通过本文就来认识一下DOM的基本概念、一些常用的API以及一些需要注意的知识点。


    1、DOM 到底是个什么鬼

    文档对象模型 (Document Object Model ,即DOM) 是HTML和XML文档的编程接口。它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容。DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。简言之,它会将web页面和脚本或程序语言连接起来。

    文档对象模型将 web 页面与到脚本或编程语言连接起来。通常是指 JavaScript,但将 HTML、SVG 或 XML 文档建模为对象并不是 JavaScript 语言的一部分。DOM模型用一个逻辑树来表示一个文档,树的每个分支的终点都是一个节点(node),每个节点都包含着对象(objects)。DOM的方法(methods)让你可以用特定方式操作这个树,用这些方法你可以改变文档的结构、样式或者内容。节点可以关联上事件处理器,一旦某一事件被触发了,那些事件处理器就会被执行。

    通俗的说,DOM就是将页面中的元素通过相应的构造方法,转换成对象,使得我们可以在JS中使用。转换成的对象的原型最终指向Node对象

    2、节点

    DOM 的最小组成单位叫做节点(node)。文档的树形结构(DOM 树),就是由各种不同类型的节点组成。每个节点可以看作是文档树的一片叶子。

    节点的类型有以下七种,浏览器提供一个原生的节点对象Node,而这七种节点都继承了Node,因此具有一些共同的属性和方法:

    • Document:整个文档树的顶层节点
    • DocumentType:doctype标签(比如<!DOCTYPE html>)
    • Element:网页的各种HTML标签(比如<body>、<a>等)
    • Attribute:网页元素的属性(比如class="right")
    • Text:标签之间或标签包含的文本
    • Comment:注释
    • DocumentFragment:文档的片段

    3、节点树

    一个文档的所有节点,按照所在的层级,可以抽象成一种树状结构。这种树状结构就是 DOM 树。它有一个顶层节点,下一层都是顶层节点的子节点,然后子节点又有自己的子节点,就这样层层衍生出一个金字塔结构,倒过来就像一棵树。

    浏览器原生提供document节点,代表整个文档。

    文档的第一层只有一个节点,就是 HTML 网页的第一个标签<html>,它构成了树结构的根节点(root node),其他 HTML 标签节点都是它的下级节点。

    除了根节点,其他节点都有三种层级关系。

    • 父节点关系(parentNode):直接的那个上级节点
    • 子节点关系(childNodes):直接的下级节点
    • 同级节点关系(sibling):拥有同一个父节点的节点

    DOM 提供操作接口,用来获取这三种关系的节点。比如,子节点接口包括firstChild(第一个子节点)和lastChild(最后一个子节点)等属性,同级节点接口包括nextSibling(紧邻在后的那个同级节点)和previousSibling(紧邻在前的那个同级节点)属性。

    4、节点类型 Node.nodeType

    nodeType属性返回一个整数值,表示节点的类型。

    document.nodeType // 9
    上面代码中,文档节点的类型值为9。

    Node 对象定义了几个常量,对应这些类型值。如:
    document.nodeType === Node.DOCUMENT_NODE // true
    上面代码中,文档节点的nodeType属性等于常量Node.DOCUMENT_NODE。

    不同节点的nodeType属性值和对应的常量如下。

    文档节点(document):9,对应常量Node.DOCUMENT_NODE
    元素节点(element):1,对应常量Node.ELEMENT_NODE
    属性节点(attr):2,对应常量Node.ATTRIBUTE_NODE
    文本节点(text):3,对应常量Node.TEXT_NODE
    文档片断节点(DocumentFragment):11,对应常量Node.DOCUMENT_FRAGMENT_NODE
    文档类型节点(DocumentType):10,对应常量Node.DOCUMENT_TYPE_NODE
    注释节点(Comment):8,对应常量Node.COMMENT_NODE

    最常用的有两个,一定要记住:元素节点的值 1 和文本节点的值 3

    确定节点类型时,使用nodeType属性是常用方法。如:

    var node = document.documentElement.firstChild;
    if (node.nodeType === Node.ELEMENT_NODE) { // 或者直接写成 node.nodeType === 1
      console.log('该节点是元素节点');
    }
    

    5、常用的DOM操作

    • createElement
      createElement通过传入指定的一个标签名来创建一个元素,如果传入的标签名是一个未知的,则会创建一个自定义的标签,注意:IE8以下浏览器不支持自定义标签。
      如:var div = document.createElement("div");

    • appendChild
      appendChild 即将指定的节点添加到调用该方法的节点的子元素的末尾。调用方法如下:parent.appendChild(child);
      child节点将会作为parent节点的最后一个子节点。

    • document.getElementById
      这个接口很简单,根据元素id返回元素,返回值是Element类型,如果不存在该元素,则返回null。
      使用这个接口有几点要注意:
      (1)元素的Id是大小写敏感的,一定要写对元素的id
      (2)HTML文档中可能存在多个id相同的元素,则返回第一个元素(当然多个同名id是不符合规范的)
      (3)只从文档中进行搜索元素,如果创建了一个元素并指定id,但并没有添加到文档中,则这个元素是不会被查找到的

    • document.getElementsByTagName
      这个接口根据元素标签名获取元素,返回一个即时的HTMLCollection类型

    • document.getElementsByClassName
      这个API是根据元素的class返回一个即时的HTMLCollection,

    • document.querySelectordocument.querySelectorAll
      这两个api很相似,通过css选择器来查找元素,注意选择器要符合CSS选择器的规则。

    • childNodes:返回一个即时的NodeList,表示元素的子节点列表,子节点可能会包含文本节点,注释节点等。
      children:一个即时的HTMLCollection,子节点都是Element,IE9以下浏览器不支持。

    • getAttribute
      getAttribute返回指定的特性名相应的特性值,如果不存在,则返回null或空字符串。用法如下:
      var value = element.getAttribute("id");

    • getBoundingClientRect
      getBoundingClientRect用来返回元素的大小以及相对于浏览器可视窗口的位置,用法如下:var clientRect = element.getBoundingClientRect();
      clientRect是一个DOMRect对象,包含left,top,right,bottom,它是相对于可视窗口的距离,滚动位置发生改变时,它们的值是会发生变化的。除了IE9以下浏览器,还包含元素的height和width等数据,具体可查看MDN链接

    6、DOM 的各种 API

    由于DOM中的API非常多,这里不一一列举,仅列出几个需要注意的,其余的可以点击链接,查看相应的MDN文档。

    这三对API的区别需要了解一下:

    • isEqualNodeisSameNode
      isEqualNode 表示相等,即两个节点的值是相等的
      isSameNode 表示相同,即两个节点就是同一个
      注意,节点中使用===运算符,指的是same相同的一个节点。

    • innerTexttextContent
      1.textContent 会获取所有元素的内容,包括<script><style> 元素,然而 innerText不会。
      2.innerText 受 CSS 样式的影响,并且不会返回隐藏元素的文本,而textContent会。
      3.由于 innerText 受 CSS 样式的影响,它会触发重排(reflow),但textContent 不会。
      4.与 textContent 不同的是, 在 Internet Explorer (对于小于等于 IE11 的版本) 中对 innerText 进行修改, 不仅会移除当前元素的子节点,而且还会永久性地破坏所有后代文本节点(所以不可能再次将节点再次插入到任何其他元素或同一元素中)。

    • innerTextinnerHTML
      innerText 表示 将里面的内容都一律看做文本
      innerHTML 会将内容看做HTML元素(包括标签甚至script脚本),慎用

    7、一些需要注意的知识点

    • DOM的最小组成单位叫做 Node
    • 节点的类型有七种 :DocumentDocumentTypeElementAttributeTextCommentDocumentFragment(详细请看上文“4、节点类型 Node.nodeType”)
    • DOM 树的根节点是 html
    • document.body.nodeName得到的结果是'BODY',(注意,nodeName得到的节点名称都是大写,除了svg)
    • 有这样的html结构,求x.nextSibling 的值是
    <div id=x></div>
    <div id=y></div>
    

    结果为:回车构成的文本节点,因为nextSibling属性包括文本节点(如回车、空格)、注释节点等。

    • 有这样的HTML结构,求parent1.childNodes 的值
    <div id=parent1><div id=child1></div></div>
    

    结果为: {0:child1, length:1} 伪数组

    • parent.childNodes 是动态集合。所谓动态集合就是一个活的集合,DOM树删除或新增一个相关节点,都会立刻反映在NodeList接口之中。
      document.querySelectorAll方法返回的是一个静态集合。DOM内部的变化,并不会实时反映在该方法的返回结果之中。
    • HTMLCollection与NodeList的区别有:
      HTMLCollection实例对象的成员只能是Element节点,NodeList实例对象的成员可以包含其他节点。
      HTMLCollection实例对象可以用id属性或name属性引用节点元素,NodeList只能使用数字索引引用。
    • ChildNode接口用于处理子节点(包含但不限于Element子节点)。Element节点、DocumentType节点和CharacterData接口,部署了ChildNode接口。凡是这三类节点(接口),都可以使用:remove()before()after()replaceWith()

    8、参考链接

    相关文章

      网友评论

        本文标题:JavaScript 中的 文档对象模型DOM

        本文链接:https://www.haomeiwen.com/subject/npfneftx.html