• DOM


    1.DOM

    DOM 是 JavaScript 操作网页的接口,全称为“文档对象模型”(Document Object Model)。它的作用是将网页转为一个 JavaScript 对象,从而可以用脚本进行各种操作(比如增删内容)。
    
    浏览器会根据 DOM 模型,将结构化文档(比如 HTML 和 XML)解析成一系列的节点,再由这些节点组成一个树状结构(DOM Tree)。所有的节点和最终的树状结构,都有规范的对外接口。
    
    DOM 只是一个接口规范,可以用各种语言实现。所以严格地说,DOM 不是 JavaScript 语法的一部分,但是 DOM 操作是 JavaScript 最常见的任务,离开了 DOM,JavaScript 就无法控制网页。另一方面,JavaScript 也是最常用于 DOM 操作的语言。后面介绍的就是 JavaScript 对 DOM 标准的实现和用法。

    2.节点

    DOM 的最小组成单位叫做节点(node)。文档的树形结构(DOM 树),就是由各种不同类型的节点组成。每个节点可以看作是文档树的一片叶子。
    
    节点的类型有七种。
    
    Document:整个文档树的顶层节点
    DocumentType:doctype标签(比如<!DOCTYPE html>)
    Element:网页的各种HTML标签(比如<body>、<a>等)
    Attr:网页元素的属性(比如class="right")
    Text:标签之间或标签包含的文本
    Comment:注释
    DocumentFragment:文档的片段
    浏览器提供一个原生的节点对象Node,上面这七种节点都继承了Node,因此具有一些共同的属性和方法。

    3.节点树

    一个文档的所有节点,按照所在的层级,可以抽象成一种树状结构。这种树状结构就是 DOM 树。它有一个顶层节点,下一层都是顶层节点的子节点,然后子节点又有自己的子节点,就这样层层衍生出一个金字塔结构,又像一棵树。
    
    浏览器原生提供document节点,代表整个文档。
    
    document
    // 整个文档树
    文档的第一层有两个节点,第一个是文档类型节点(<!doctype html>),第二个是 HTML 网页的顶层容器标签<html>。后者构成了树结构的根节点(root node),其他 HTML 标签节点都是它的下级节点。
    
    除了根节点,其他节点都有三种层级关系。
    
    父节点关系(parentNode):直接的那个上级节点
    子节点关系(childNodes):直接的下级节点
    同级节点关系(sibling):拥有同一个父节点的节点
    DOM 提供操作接口,用来获取这三种关系的节点。比如,子节点接口包括firstChild(第一个子节点)和lastChild(最后一个子节点)等属性,
    同级节点接口包括nextSibling(紧邻在后的那个同级节点)和previousSibling(紧邻在前的那个同级节点)属性。

    1.Node 接口

    所有 DOM 节点对象都继承了 Node 接口,拥有一些共同的属性和方法。这是 DOM 操作的基础。
    1.1 Node.prototype.nodeType   //nodeType属性返回一个整数值,表示节点的类型。
    
    document.nodeType //9
    
    不同节点的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
    
    
    /*
    var node = document.documentElement.firstChild;
    if (node.nodeType === Node.ELEMENT_NODE) {
      console.log('该节点是元素节点');
    }
    */
    
    
    1.2 Node.prototype.nodeName    //nodeName 属性返回节点名称
    不同节点的nodeName属性值如下。
    
    文档节点(document):#document
    元素节点(element):大写的标签名
    属性节点(attr):属性的名称
    文本节点(text):#text
    文档片断节点(DocumentFragment):#document-fragment
    文档类型节点(DocumentType):文档的类型
    注释节点(Comment):#comment
    
    1.3 Node.prototype.nodeValue //nodeValue 属性返回一个字符串,表示当前节点的本身的文本值,该属性可读写
    只有文本节点(text)、注释节点(comment)和属性节点(attr)有文本值,因此这三类节点的nodeValue可以返回结果,
    其他类型的节点一律返回null。同样的,也只有这三类节点可以设置nodeValue属性的值,其他类型的节点设置无效。
    /*
    // HTML 代码如下
    // <div id="d1">hello world</div>
    var div = document.getElementById('d1');
    div.nodeValue // null
    div.firstChild.nodeValue // "hello world"
    
    */
    
    
    1.4 Node.prototype.textContent  // 属性返回当前节点和他所有后代节点的文本内容
    
    /*
    // HTML 代码为
    // <div id="divA">This is <span>some</span> text</div>
    
    document.getElementById('divA').textContent
    // This is some text
    */
    
    
    
    1.5 Node.prototype.baseURI   // baseURI 属性返回一个字符串, 表示当前网页的绝对路劲。浏览器根据这个属性,计算网页的相对路径的URL,该属性为只读
    
    /*
    // 当前网页的网址为
    // http://www.example.com/index.html
    document.baseURI
    // "http://www.example.com/index.html"
    
    */
    该属性的值一般由当前网址的 URL(即window.location属性)决定,但是可以使用 HTML 的<base>标签,改变该属性的值。
    
    
    1.6 Node.prototype.ownerDocument //Node.ownerDocument 属性返回当前节点所在的顶层文档对象,及 document 对象
    
    /*
    var d = p.ownerDocument;
    d === document // true
    */
    
    1.7 Node.prototype.nextSibling    //属性返回紧跟在当前节点后面的第一个同级节点,如果当前节点后面没有同级节点,则返回null
    
    /*
    // HTML 代码如下
    // <div id="d1">hello</div><div id="d2">world</div>
    var d1 = document.getElementById('d1');
    var d2 = document.getElementById('d2');
    
    d1.nextSibling === d2 // true
    */
    
    1.8 Node.prototype.previousSibling  //返回当前节点前面的,距离最近的一个同级节点,没有返回 null
    
    /*
    // HTML 代码如下
    // <div id="d1">hello</div><div id="d2">world</div>
    var d1 = document.getElementById('d1');
    var d2 = document.getElementById('d2');
    
    d2.previousSibling === d1 // true
    
    */
    
    
    
    1.9 Node.prototype.parentNode   //返回当前节点的父节点,对于一个节点来说,他的父节点只可能是三种类型: 元素节点(element) ,文档节点(document),和文档片段节点(documentfragment)
    
    /*
    if (node.parentElement) {
      node.parentElement.style.color = 'red';
    }
    */
    上面代码中,父元素节点的样式设定了红色。
    
    由于父节点只可能是三种类型:元素节点、文档节点(document)和文档片段节点(documentfragment)。parentElement属性相当于把后两种父节点都排除了。
    
    
    1.11 Node.prototype.firstChild 、Node.prototype.lastChild // firstChild 返回当前节点的第一个子节点,last 返回当前节点的最后一个子节点
    
    /*
    // HTML 代码如下
    // <p id="p1"><span>First span</span></p>
    var p1 = document.getElementById('p1');
    p1.firstChild.nodeName // "SPAN"
    */
    /*
    // HTML 代码如下
    // <p id="p1">
    //   <span>First span</span>
    //  </p>
    var p1 = document.getElementById('p1');
    p1.firstChild.nodeName // "#text"
    
    */
    
    
    1.12  Node.prototype.childNodes   //属性返回一个类似数组的对象,  nodelist 成员包括当前节点的所有子节点
    
    
    var children = document.querySelector('ul').childNodes;
    
    
    1.13  Node.prototype.isConnected   // 属性返回一个布尔值,表示当前节点是否在文档中
    
    /*
    var test = document.createElement('p');
    test.isConnected // false
    
    */
    
    
    方法:
    
    2.1 Node.prototype.appendChild()  //appendChild()方法接受一个节点对象作为参数,将其作为最后一个子节点,插入当前节点。该方法的返回值就是插入文档的子节点。
    var p = document.createElement('p');
    document.body.appendChild(p);
    
    
    
    2.2 Node.prototype.hasChildNodes()   //hasChildNodes方法返回一个布尔值,表示当前节点是否有子节点
    
    /*
    var foo = document.getElementById('foo');
    
    if (foo.hasChildNodes()) {
      foo.removeChild(foo.childNodes[0]);
    }
    
    */
    
    2.3 Node.prototype.cloneNode()    // 克隆一个节点,他接受一个布尔值作为参数,表示是否同时克隆子节点,返回值是一个克隆出来的新节点
    
    /*
    var cloneUL = document.querySelector('ul').cloneNode(true); //方法用于克隆一个节点。它接受一个布尔值作为参数,表示是否同时克隆子节点。它的返回值是一个克隆出来的新节点。
    */
    
    
    2.4 Node.prototype.insertBefore()   //将某个节点插入父节点内部指定的位置
    
    /*
    var insertedNode = parentNode.insertBefore(newNode, referenceNode);
    var p = document.createElement('p');
    document.body.insertBefore(p, document.body.firstChild);
    */
    
    
    2.5 Node.prototype.removeChild() //方法接收一个子节点作为参数,用于从当前节点移除该子节点
    /*
    var divA = document.getElementById('A');
    divA.parentNode.removeChild(divA);
    */
    
    
    2.6 Node.prototype.replaceChild() //replaceChild方法用于将一个新的节点,替换当前节点的某一个子节点。
    
    /*
    var replacedNode = parentNode.replaceChild(newChild, oldChild);
    var divA = document.getElementById('divA');
    var newSpan = document.createElement('span');
    newSpan.textContent = 'Hello World!';
    divA.parentNode.replaceChild(newSpan, divA);
    */
    
    
    2.7 Node.prototype.contains()  //contains方法返回一个布尔值,表示参数节点是否满足以下三个条件之一。
    
    /*
    参数节点为当前节点。
    参数节点为当前节点的子节点。
    参数节点为当前节点的后代节点。
    document.body.contains(node)
    */
    
    
    2.8 Node.prototype.compareDocumentPosition()   // compareDocumentPosition方法的用法,与contains方法完全一致,返回一个六个比特位的二进制值,表示参数节点与当前节点的关系。
    
    二进制值    十进制值    含义
    000000    0    两个节点相同
    000001    1    两个节点不在同一个文档(即有一个节点不在当前文档)
    000010    2    参数节点在当前节点的前面
    000100    4    参数节点在当前节点的后面
    001000    8    参数节点包含当前节点
    010000    16    当前节点包含参数节点
    100000    32    浏览器内部使用
    
    /*
    // HTML 代码如下
    // <div id="mydiv">
    //   <form><input id="test" /></form>
    // </div>
    
    var div = document.getElementById('mydiv');
    var input = document.getElementById('test');
    
    div.compareDocumentPosition(input) // 20
    input.compareDocumentPosition(div) // 10
    */
    
    
    2.9 Node.prototype.isEqualNode(),Node.prototype.isSameNode() //isEqualNode方法返回一个布尔值,用于检查两个节点是否相等。所谓相等的节点,指的是两个节点的类型相同、属性相同、子节点相同。
    
    /*
    
    var p1 = document.createElement('p');
    var p2 = document.createElement('p');
    
    p1.isEqualNode(p2) // true
    */
    
    
    2.10 Node.prototype.normalize() //normalize方法用于清理当前节点内部的所有文本节点(text)。它会去除空的文本节点,并且将毗邻的文本节点合并成一个,也就是说不存在空的文本节点,以及毗邻的文本节点。
    
    /*
    var wrapper = document.createElement('div');
    
    wrapper.appendChild(document.createTextNode('Part 1 '));
    wrapper.appendChild(document.createTextNode('Part 2 '));
    
    wrapper.childNodes.length // 2
    wrapper.normalize();
    wrapper.childNodes.length // 1
    */
    
    2.11 Node.prototype.getRootNode()   // getRootNode()方法返回当前节点所在文档的根节点document,与ownerDocument属性的作用相同。
    
    /*
    document.body.firstChild.getRootNode() === document
    // true
    document.body.firstChild.getRootNode() === document.body.firstChild.ownerDocument
    // true
    
    该方法可用于document节点自身,这一点与document.ownerDocument不同。
    
    document.getRootNode() // document
    document.ownerDocument // null
    */
  • 相关阅读:
    [COCI2013]DLAKAVAC
    [TJOI2013]最长上升子序列
    AGC040E Prefix Suffix Addition
    AGC010E Rearranging
    AGC021F Trinity
    AGC002F Leftmost Ball
    JOISC2019D ふたつのアンテナ
    LOJ6210 「美团 CodeM 决赛」tree
    Luogu P3781 [SDOI2017]切树游戏
    Problem. M
  • 原文地址:https://www.cnblogs.com/zy09/p/14442432.html
Copyright © 2020-2023  润新知