DOM是JavaScript操作网页的接口,全称为“文档对象模型”(Document Object Model)。它的作用是将网页转为一个JavaScript对象,从而可以用脚本进行各种操作(比如增删内容)。DOM的最小组成单位叫做节点(node),节点的类型常见的有四种:
- Document:整个文档树的顶层节点。
- Element:网页的各种标签,比如
<body>
。- Text:标签之间或标签包含的文本。
- Attr:网页的元素属性,比如
class="right"
。
一、Node
所有DOM节点对象都继承了Node
接口,拥有一些共同的属性和方法。这是DOM操作的基础。
1.1 对象属性
baseURI
属性返回一个字符串,表示当前网页的绝对路径(浏览器根据这个属性计算网页上的相对路径的URL)。该属性的值一般由当前网址的URL(即window.location
属性)决定。可以用HTML的<base>
标签改变该属性的值。isConnected
属性返回一个布尔值,表示当前节点是否在文档之中。nodeType
属性返回一个整数值,表示当前节点的类型。通过Node.DOCUMENT_XXX来定义了上述各种类型。nodeName
属性返回一个字符串,表示当前节点的名称。nodeValue
属性返回一个字符串,表示当前节点本身的文本值。只有元素、文本、注释有文本值,其他类型的节点一律返回null
。textContent
属性返回一个字符串,表示当前节点和它的所有后代节点的文本内容。它会自动忽略当前节点内部的HTML标签,返回所有文本内容。parentNode
属性返回当前节点的父节点。对于一个节点来说,它的父节点只可能是三种类型:文档节点(document)、元素节点(element)和文档片段节点(documentfragment)。nextSibling
属性返回当前节点后的第一个同级节点(元素、文本、注释)。如没有,则返回null
。previousSibling
属性返回当前节点前的第一个同级节点(元素、文本、注释)。如没有,则返回null
。firstChild
属性返回当前节点的第一个子节点(元素、文本、注释)。如当前节点没有子节点,则返回null
。lastChild
属性返回当前节点的最后一个子节点(元素、文本、注释)。如当前节点没有子节点,则返回null
。childNodes
属性返回一个类数组对象(NodeList
集合),成员包括当前节点的所有子节点(元素、文本、注释)。由于
NodeList
对象是一个动态集合,一旦子节点发生变化,立刻会反映在返回结果之中。
以上返回文本节点时,如果当前节点前面有空格,该属性会返回一个文本节点,内容为空格。
1.2 对象方法
hasChildNodes
方法用于表示当前节点是否有子节点。insertBefore
方法用于将某个节点插入该节点的指定子节点的前面(如果所要插入的节点是当前DOM现有的节点,则该节点将从原有的位置移除,插入新的位置)。该方法第一个参数是所要插入的节点newNode
,第二个参数是子节点referenceNode
(如果第二个参数为null
,则新节点将插在当前节点内部的最后位置,即变成最后一个子节点)。返回值是插入的新节点newNode
。removeChild
方法用于从当前节点移除该子节点。该方法参数是要移除的子节点。返回值是移除的节点。replaceChild
方法用于将一个新的节点,替换当前节点的某个子节点。该方法第一个参数newChild
是用来替换的新节点,第二个参数oldChild
是要替换走的子节点。返回值是替换走的那个节点oldChild
。getRootNode()
方法返回当前节点所在文档的根节点document。
二、Document
document
节点对象代表整个文档,每张网页都有自己的document
对象。该节点有两个子节点:第一个是文档类型节点(<!doctype html>
);第二个是HTML网页的顶层容器标签<html>
,它后者构成了树结构的根节点(root node),其他 HTML 标签节点都是它的下级节点。document
对象有不同的办法可以获取:
- 正常的网页:使用
document
或window.document
。 iframe
的网页:使用iframe
节点的contentDocument
属性。
2.1 对象属性
doctype
属性返回所拥有的<DOCTYPE>
节点。document.firstChild
通常就返回这个节点。documentElement
属性返回当前文档的根元素节点。document.lastChild
通常就返回这个节点。head
属性指向<head>
节点。这个属性总是存在的,如果网页源码里面省略了,浏览器会自动创建。body
属性返回<body>
节点。这个属性总是存在的,如果网页源码里面省略了,浏览器会自动创建。location
属性是浏览器提供的原生对象,提供URL相关的信息和操作方法。cookie
属性是浏览器提供的原生对象,用来操作浏览器 Cookie。
2.2 对象方法
querySelectorAll
方法返回匹配指定选择器的元素节点,返回一个NodeList
实例。返回结果不是动态集合,不会实时反映元素节点的变化。如果有多个节点满足匹配条件,则返回第一个匹配的节点。如果没有发现匹配的节点,则返回null
。它不支持CSS伪元素的选择器(比如:first-line
和:first-letter
)和伪类的选择器(比如:link
和:visited
),即无法选中伪元素和伪类。getElementById
方法返回匹配指定id
属性的元素节点,返回一个NodeList
实例,不可实时反映文档的变化。getElementsByName
方法返回匹配name
属性的元素节点,返回一个NodeList
实例,不可实时反映文档的变化。getElementsByTagName
方法返回匹配的标签节点,返回一个HTMLCollection
实例,可以实时反映文档的变化。getElementsByClassName
方法返回匹配的类名节点,返回一个HTMLCollection
实例,可以实时反映文档变化。createElement
方法用来生成元素节点,并返回该节点。createAttribute
方法生成一个新的属性节点(Attr
实例),并返回该节点。createEvent
方法生成一个事件对象(Event
实例),该对象可以被element.dispatchEvent
方法使用,触发指定事件。方法的参数是事件类型,如UIEvents
、MouseEvents
、HTMLEvents
等。事件处理参考下一章。
三、attribute
3.1 对象属性
Element.attributes
属性返回一个类似数组的动态对象,成员是该元素标签的所有属性节点对象,属性的实时变化都会反映在这个节点对象上。属性本身是一个对象(Attr
对象)。所以上述类似数组返回的都是属性节点对象,而不是属性值。属性节点对象有name
和value
属性,对应该属性的属性名和属性值,等同于nodeName
属性和nodeValue
属性。
HTML属性名转JS键名:转为JS属性名时,一律采用小写;如果属性名包括多个单词,则采用骆驼拼写法。有些HTML属性名是JavaScript的保留字,转为JS属性时必须改名,主要是以下两个:
for
属性改为htmlFor
class
属性改为className
Element.dataset
属性返回一个对象,可以从这个对象读写data-
属性。如<div data-timestamp="1522907809292"></div>
,<div>
元素有一个自定义的data-timestamp
属性,用来为该元素添加一个时间戳。
HTML属性名转JS键名:转成
dataset
的键名时,连词线后面如果跟着一个小写字母,那么连词线会被移除,该小写字母转为大写字母,其他字符不变。反过来dataset
的键名转成属性名时,所有大写字母都会被转成连词线+该字母的小写形式,其他字符不变。如dataset.helloWorld
会转成data-hello-world
。
3.2 对象方法
hasAttribute
方法返回一个布尔值,表示当前元素节点是否包含指定属性。getAttribute
方法返回当前元素节点的指定属性。如果指定属性不存在,则返回null
。setAttribute
方法用于为当前元素节点新增属性。如果同名属性已存在,则相当于编辑已存在的属性。removeAttribute
方法用于移除指定属性。