第14章 DOM

DOM文档对象模型,是html和xml文档的编程接口。

节点层级

任何HTML或XML文档都可以用DOM表示为一个由节点构成的层级结构。document节点表示每个文档的根节点。根节点的唯一子节点是html元素,我们称之为文档元素(documentElement)。

Document
  Element <html>
    Element <head>
      Element <title>
      Element <meta>
    Element <body>
      Element <p>
        Element <a>
          Element <img>

html中的每段标记都可以表示为这个树形结构中的一个节点,DOM中总共有12中节点类型,这些类型都继承一种基本类型。

Node类型

在javascript中,所有节点类型都继承自Node类型,因此所有类型都共享相同的基本属性和方法。每个节点都有nodeType属性,表示该节点的类型。

Node类型上的12个数值常量表示为:

  • Node.ELEMENT_NODE 元素节点 1,nodeName始终等于元素的标签名,nodeValue始终为null
  • Node.ATTRIBUTE_NODE 属性节点 2
  • Node.TEXT_NODE 文本节点 3
  • Node.CDATA_SECTION_NODE CDATA节点 4
  • Node.ENTITY_REFERENCE_NODE 实体引用节点 5
  • Node.ENTITY_NODE 实体节点 6
  • Node.PROCESSING_INSTRUCTION_NODE 注释节点 7
  • Node.COMMENT_NODE 注释节点 8
  • Node.DOCUMENT_NODE 文档节点 9
  • Node.DOCUMENT_TYPE_NODE 文档类型节点 10
  • Node.DOCUMENT_FRAGMENT_NODE 文档片段节点 11
  • Node.NOTATION_NODE 注释节点 12 nodeName与nodeValue保存着有关节点的信息。

每个节点都有一个childNodes属性,其中包含一个NodeList的实例,firstChild和lastChild分别指向childNodes中的第一个和最后一个子节点。

每个节点都有一个parentNode属性,指向其DOM树中的父元素。 hasChildNodes()返回节点是否有子节点。

操作节点

插入节点:

appendChild() 方法将一个节点添加到父节点的末尾。

insertBefore() 添加节点到开头。

替换节点:

replaceChild()方法接收两个参数:要插入的节点和要替换的节点。要替换的节点会被返回并从文档树中完全移除,要插入的节点会取而代之。

移除节点:

removeChild()

复制节点:

cloneNode(boolean)会返回与调用它的节点一模一样的节点,传入一个布尔,代表是否深复制,深复制会复制节点上所有子节点。返回的节点没有父亲节点,可通过appendChild插入文档中。

Document类型

文档对象document是HTMLDocument的实例(HTMLDocument继承Document),表示整个HTML页面。

  • nodeType等于9;
  • nodeName值为”#document”;
  • nodeValue值为null;
  • document.documentElement属性返回文档的根元素,即html标签。
  • document.body 属性返回文档的body元素,即body标签。
  • document.doctype 属性返回文档的doctype,即<!DOCTYPE>标签。
  • document.title 当前页面的标题,可修改
  • document.URL 当前页面的URL

Element类型

Element表示XML或HTML元素,对外暴露出访问元素标签名、子节点和属性的能力。

  • nodeType等于1;

  • nodeName值为元素的标签名;

  • nodeValue值为null;

  • <div id="myDiv" class="bd" title="Body text" lang="en" dir="ltr"></div>
    <script>
    let div = document.getElementById("myDiv");
    alert(div.id);           // "myDiv"
    alert(div.className);   // "bd"
    alert(div.title);        // "Body text"
    alert(div.lang);         // "en"
    alert(div.dir);          // "ltr" 语言的书写方向:从左到右
    </script>
    

    可以直接通过元素来修改标签的内容。

    与属性相关的DOM方法主要有3个:getAttribute()、setAttribute()和removeAttribute()。这些方法主要用于操纵属性。属性名不区分大小写。

    let div = document.getElementById("myDiv");
    alert(div.getAttribute("id"));      // "myDiv"
    

创建元素

document.createElement(tag)

Text类型

  • nodeType等于3;
  • nodeName值为”#text”;
  • nodeValue值为节点中包含的文本;
  • parentNode值为Element对象;
  • 不支持子节点。

DOM编程

动态添加脚本

<script src = "foo.js"></script>
<!-- 如果使用dom进行操作 -->
let script = document.createElement("script");
script.src = "foo.js";
document.body.appendChild(script);

动态添加函数

let script = document.createElement("script");
script.appendChild(document.createTextNode("function sayHi() &#123;alert('hi~');&#125;"));
document.body.appendChild(script);

动态添加样式

let link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = "style.css";
let head = document.getElementByTagName("head")[0];
head.appendChild(link);

动态添加style

let style = document.createElement("style");
style.type = "text/css";
style.appendChild(document.createTextNode("body&#123;background-color:red&#125;"));
let head = document.getElementsByTagName("head")[0];
head.appendChild(style);