DOM
DOM概述
1.DOM是什么?
- DOM全称为“文档对象模型”(Document Object Model),是一个接口规范,可以用各种语言实现。JS是最常用于DOM操作的语言。
- DOM 是 JavaScript 操作网页的接口,。它的作用是将网页转为一个 JavaScript 对象,从而可以用脚本进行各种操作(比如增删内容)。
- 浏览器会根据 DOM 模型,将结构化文档(比如 HTML 和 XML)解析成一系列的节点,再由这些节点组成一个树状结构(DOM Tree)。所有的节点和最终的树状结构,都有规范的对外接口。
2.节点
- DOM 的最小组成单位叫做节点(node)。文档的树形结构(DOM 树),就是由各种不同类型的节点组成。每个节点可以看作是文档树的一片叶子。
- 节点的类型有七种。
Document:整个文档树的顶层节点
DocumentType:doctype标签(比如)
Element:网页的各种HTML标签(比如、等)
Attr:网页元素的属性(比如class=“right”)
Text:标签之间或标签包含的文本
Comment:注释
DocumentFragment:文档的片段
浏览器提供一个原生的节点对象Node,上面这七种节点都继承了Node,因此具有一些共同的属性和方法。
3.节点树
- 像金字塔,又像一棵树。
- 浏览器原生提供document节点,代表整个文档。
- 文档的第一层有两个节点,第一个是文档类型节点(<!doctype html>),第二个是 HTML 网页的顶层容器标签。后者构成了树结构的根节点。
- 除了根节点,其他节点都有三种层级关系。
parentNode:直接的那个上级节点
childNodes:直接的下级节点,属性:firstChild和lastChild等;
sibling:拥有同一个parentNode的节点,属性:nextSibling(紧邻在后的那个同级节点)和previousSibling(紧邻在前的那个同级节点)。
Node 接口
- 所有 DOM 节点对象都继承了 Node 接口,拥有一些共同的属性和方法。这是 DOM 操作的基础。
1 属性
1.1Node.prototype.nodeType
- nodeType属性返回一个整数值,表示节点的类型。
- Node 对象定义了几个常量,对应这些类型值。
-
"确定"而不是判断,就很严谨。一般来说,在确定之前,就已经有了初步判断的结论了嘛~
1.2 Node.prototype.nodeName
- nodeName属性返回节点的名称。
- 不同节点的nodeName属性值如下。
- 文档节点(document):#document
- 元素节点(element):大写的标签名
<div> 的 nodename 就是 DIV
- 属性节点(attr):属性的名称
- 文本节点(text):#text
- 文档片断节点(DocumentFragment):#document-fragment
- 文档类型节点(DocumentType):文档的类型
- 注释节点(Comment):#comment
1.3Node.prototype.nodeValue
- nodeValue属性返回一个字符串,表示当前节点本身的文本值,该属性可读写。
- 只有文本节点(text)、注释节点(comment)和属性节点(attr)有文本值,因此这三类节点的nodeValue可以返回结果,其他类型的节点一律返回null。
- 同样的,也只有这三类节点可以设置nodeValue属性的值,其他类型的节点设置无效。
1.4Node.prototype.textContent
- textContent属性返回当前节点和它的所有后代节点的文本内容。自动忽略当前节点内部的 HTML 标签,返回所有文本内容。
- 该属性是可读写的,设置该属性的值,会用一个新的文本节点,替换所有原来的子节点。
- 注意:读取的时候忽略标签(不会把标签当作 文本),写入时如果文本中有标签,那还是文本,不会当作标签处理。(相当于写入的字符串有啥就写啥)
1.5 Node.prototype.baseURI
- baseURI属性返回一个字符串,表示当前网页的绝对路径。浏览器根据这个属性,计算网页上的相对路径的 URL。该属性为只读。
- 如果无法读到网页的 URL,baseURI属性返回null。
- 该属性的值一般由当前网址的 URL(即window.location属性)决定,但是可以使用 HTML 的标签,改变该属性的值。(设置后,就返回设置的值)
1.6 Node.prototype.ownerDocument
- Node.ownerDocument属性返回当前节点所在的顶层文档对象,即document对象。
- document对象本身的ownerDocument属性,返回null。
(有点像Object的原型是null?
1.7 Node.prototype.nextSibling
- Node.nextSibling属性返回紧跟在当前节点后面的第一个同级节点。如果当前节点后面没有同级节点,则返回null。
- 注意,该属性还包括文本节点和注释节点( )。因此如果当前节点后面有空格,该属性会返回一个文本节点,内容为空格。
- nextSibling属性可以用来遍历所有子节点。(直到它的值为null)
1.8 Node.prototype.previousSibling
- previousSibling属性返回当前节点前面的、距离最近的一个同级节点。如果当前节点前面没有同级节点,则返回null。
1.9 Node.prototype.parentNode
- parentNode属性返回当前节点的父节点。对于一个节点来说,它的父节点只可能是三种类型:元素节点(element)、文档节点(document)和文档片段节点(documentfragment)。
- 文档节点(document)和文档片段节点(documentfragment)的父节点都是null。另外,对于那些生成后还没插入 DOM 树的节点,父节点也是null。
1.10 Node.prototype.parentElement
- parentElement属性返回当前节点的父元素节点。如果当前节点没有父节点,或者父节点类型不是元素节点,则返回null。
- 由于父节点只可能是三种类型:元素节点、文档节点(document)和文档片段节点(documentfragment)。parentElement属性相当于把后两种父节点都排除了。
1.11 Node.prototype.firstChild,Node.prototype.lastChild
- firstChild属性返回当前节点的第一个子节点,如果当前节点没有子节点,则返回null。
- 注意,firstChild返回的除了元素节点,还可能是文本节点或注释节点。(比如空格)
- lastChild属性返回当前节点的最后一个子节点,如果当前节点没有子节点,则返回null。用法与firstChild属性相同。
1.12 Node.prototype.childNodes
- childNodes属性返回一个类似数组的对象(NodeList集合),成员包括当前节点的所有子节点。
- 使用该属性,可以遍历某个节点的所有子节点。
- 文档节点(document)就有两个子节点:文档类型节点(docType)和 HTML 根元素节点。
- 注意,除了元素节点,childNodes属性的返回值还包括文本节点和注释节点。如果当前节点不包括任何子节点,则返回一个空的NodeList集合。由于NodeList对象是一个动态集合,一旦子节点发生变化,立刻会反映在返回结果之中。
1.13 Node.prototype.isConnected
- isConnected属性返回一个布尔值,表示当前节点是否在文档之中。
- 上面代码中,test节点是脚本生成的节点,没有插入文档之前,isConnected属性返回false,插入之后返回true。
2 方法
2.1 Node.prototype.appendChild()
- appendChild()方法接受一个节点对象作为参数,将其作为最后一个子节点,插入当前节点。该方法的返回值就是插入文档的子节点。
- 如果参数节点是 DOM 已经存在的节点,appendChild()方法会将其从原来的位置,移动到新位置。
var p = document.createElement('p');
document.body.appendChild(p);
-
==如果appendChild()方法的参数是DocumentFragment节点,那么插入的是DocumentFragment的所有子节点,而不是DocumentFragment节点本身。返回值是一个空的DocumentFragment节点。?==其实不太懂。因为书上是说这个创建的p就是文档碎片。但不也直接本身插入了?
-
书里的补充:createTextNode方法;可以创建一个文本节点。跟createElement(创建一个元素节点)其实差不多。
2.2 Node.prototype.hasChildNodes()
- hasChildNodes方法返回一个布尔值,表示当前节点是否有子节点。
- 注意,子节点包括所有类型的节点,并不仅仅是元素节点。哪怕节点只包含一个空格,hasChildNodes方法也会返回true。
- 判断一个节点有没有子节点,有许多种方法,下面是其中的三种。
node.hasChildNodes()
node.firstChild !== null
node.childNodes && node.childNodes.length > 0
hasChildNodes方法结合firstChild属性和nextSibling属性,可以遍历当前节点的所有后代节点。
Node.prototype.insertBefore()
-
insertBefore方法用于将某个节点插入父节点内部的指定位置
-
var insertedNode = parentNode.insertBefore(newNode, referenceNode);
-
如果insertBefore方法的第二个参数为null,则新节点将插在当前节点内部的最后位置,即变成最后一个子节点。
-
注意,如果所要插入的节点是当前 DOM 现有的节点,则该节点将从原有的位置移除,插入新的位置。
-
由于不存在insertAfter方法,如果新节点要插在父节点的某个子节点后面,可以用insertBefore方法结合nextSibling属性模拟。