DOM API
DOM
DOM (Document Object Model, 文档对象模型)是 JS 操作网页的接口。
浏览器将结构化文档 (HTML, XML) 解析为一系列的节点,形成树状结构(DOM Tree),并且提供了标准的对外接口。
节点
DOM Tree 由不同类型的节点构成,包括 7 类, 都继承自 Node 对象:
Document整个树的顶层节点DocumentType即 doctype 标签节点Element各种 HTML 标签Attr网页元素的属性Text标签之间或内部的文本Comment注释DocumentFragment文档片段
浏览器原生提供的 document 节点,代表了整个文档对象树。它的第一层有两个节点,一个doctype,一个html,后者构成了树结构的根节点。
不同的节点之间有三种关系:
- parentNode
- childNodes
- sibling
对于一个 DOM 节点,自带了lastChild nextSibling 等接口以获取目标节点。
Node 接口
所有 DOM 节点都继承了 Node 接口,Node 接口提供了一些共同的属性和方法。
属性
| 属性名 | 描述 |
|---|---|
el.nodeType | 返回一个枚举常量整数值,表示节点类型,包阔上一节提供的节点类型。 |
el.nodeName | 返回节点名称,元素节点的话就是标签名称,其他的就是 # + 类型,比如 #text #document-fragment |
el.nodeValue | 只有 text comment attr 三类节点有值,返回文本值 |
el.textContent | 返回节点内部的(包括子节点)的文本内容,忽略 HTML 标签,该属性可读可写 |
el.baseURI | 表示当前网页的绝对路径 |
el.ownerDocument | 返回当前节点所在的顶层文档对象,即 document 对象 |
el.nextSibling | 下一个兄弟 |
el.previousSibling | 上一个兄弟 |
el.parentNode | 父节点,可能时 element, document, documentFragment |
el.parentElement | 父元素节点,如果无父或非 element,则 null |
el.firstChild / lastChild | 子节点 |
el.childNodes | 返回子节点组成的 类数组对象 NodeList 集合 |
方法
| 方法名 | 描述 |
|---|---|
el.appendChild() | 将参数节点对象插入至当前节点末尾, 如果插入一个文档片段,那插入的是片段中的所有子节点 |
el.hasChildNodes() | 当前节点是否有子节点 |
el.cloneNode() | 克隆节点 |
el.insertBefore() | 在给定的子节点之前插入新子节点 |
el.removeChild() | 删除指定子节点 |
el.replaceChild() | 替换指定子节点 |
el.contain() | 判断参数节点是否是当前节点或后代节点 |
el.isEqualNode() | 判断节点是否相等 |
NodeList 与 HTMLCollection
NodeList 和 HTMLCollection 都是类数组对象,存储了多个节点, 可以用Array.prototype.slice.call来转为真数组,区别在于,NodeList 可包含各种类型的节点,而 HTMLCollection 只能包含 HTML Element 节点。
el.childNodes 和 querySelectAll 的返回值都是 NodeList
返回 HTMLCollection 实例的,主要是一些 Document 对象的集合属性,比如document.links、document.forms、document.images等。
ParentNode 接口 与 ChildNode 接口
Mixin(混入) 是一种编程设计模式,用于在不使用完整继承的情况下,向类中添加可复用的功能。它通常是一个提供特定方法或行为的类,但不独立使用,也不代表一个完整的“类型”。多重继承是 Mixin 的一种实现,是一种受控的、有约束的多重继承。
当一个节点有子子节点,那么它就 mixin 了 ParentNode 接口;同理,一个子节点被加到一个父节点之下,那么它也 mixin 了 childNode
ParentNode 接口提供的属性方法:
| 属性和方法 | 描述 |
|---|---|
| children | 返回子节点 HTMLCollection |
| firstElementChild | --- |
| lastElementChild | --- |
| childElementCount | --- |
| append | 尾部追加 |
| prepend | 在头部加 |
ChildNode 接口提供的属性方法:
| 属性和方法 | 描述 |
|---|---|
| remove | 直接把自己自己从父节点中移除 |
| before | 在节点前面插入兄弟 |
| after | 在节点后面插入兄弟 |
| replaceWith | --- |
Document 节点
获取 document :
- document
- iframe 节点的 contentDocument
- ownerDocument
属性
快捷方式属性:直接获取某些特定节点, 比如
- document.doctype
- document.body
- document.fullscreenElement
节点集合属性:直接获取特定元素的节点集合,比如
- document.links
- document.image
- document.forms
静态信息属性:返回文档信息,比如
- document.documentURI 返回当前网页地址
- document.domain 返回域名,不包含协议和端口
- document.location 返回一个 Location 对象,包含域名、 URI 、协议等等信息
- document.lastModified
- document.title
文档状态属性:
document.hidden如页面最小化,或者切换到其他标签页了,都会返回 truedocument.visibilityState- visible 可见
- hidden 不可见
- prerender 正在渲染,不可见
- unloaded 页面已卸载
document.readyState包括 loading interactive complete- 浏览器开始下载和解析 HTML 文档,
loading。 - 遇到 HTML 文档中的
<script>元素,并且没有async或defer属性,就暂停解析,开始执行脚本,这时还是loading。 - HTML 文档解析完成,document.readyState属性变成
interactive。 - 浏览器等待图片、样式表、字体文件等外部资源加载完成,一旦全部加载完成,
complete。
- 浏览器开始下载和解析 HTML 文档,
document.cookie操作浏览器 cookiedocument.currentScript当前脚本所在的 DOM 节点document.implementation创建新的Document对象
方法
清朝的 API 现在都是用 innerHTML, textContent了,了解即可。
document.open()清除 document 的所有内容,进入可写状态document.write()可以向文档写入内容document.close()关闭文档,不可写
选择元素
- document.querySelector() / document.querySelectorAll() --> NodeList
document.getElementsByTagName()--> HTMLCollectiondocument.getElementsByClassName()--> HTMLCollectiondocument.getElementsByName()document.getElementsById()document.elementFromPoint(x,y)返回位于 x , y 处的最上层的元素节点
创建元素
document.createElement(tagName)document.createTextNode()--> 在展示用户输入的时候,可以用这个函数确保代码是纯文本渲染,对于特殊字符会转义,避免XSS攻击document.createAttribute()--> 一般都是直接给元素 setAttribute, 不需要创建属性节点这样绕路document.createComment()document.createDocumentFragment()
事件
- document.createEvent() / document.dispatchEvent()
- document.addEventListener(),document.removeEventListener()
跨document的
document.adoptNode()把节点从原来所在的文档或文档片段中移除,归属到当前 document 对象,只是改变归属,但没有插入document.importNode()从原来的文档或片段中拷贝,归属到当前 document 对象,也没有插入
文档遍历
document.createNodeIterator()创建子节点遍历器,遍历器包括 nextNode() previousNode() 等方法document.createTreeWalker()类似
文档命令
如果document.designMode属性设为on,那么整个文档用户可编辑;如果元素的contenteditable属性设为true,那么该元素可编辑。
这两种情况下,可以使用document.execCommand()方法,改变内容的样式,比如document.execCommand('bold')会使得字体加粗。
document.execCommand()document.queryCommandSupported()document.queryCommandEnabled()
Element 节点
Element 对象继承了 Node 接口,自己本身也是一个接口,再往下还有 a 标签对应的 HTMLAnchorElement() ,button 标签对应的 HTMLButtonElement()
属性
元素特性
| 属性 | 说明 |
|---|---|
| id | --- |
| tagName | --- |
| title | 文字提示 |
| accessKey | 设置元素的快捷键,alt + 快捷键可以让元素获取焦点 |
| dir | 文字方向 |
| lang | 语言 |
元素状态
| 属性 | 说明 |
|---|---|
| style | --- |
| attributes | 属性类数组对象 |
| className | 一个字符串,class之间空格分割 |
| classList | 一个类数组对象,具有 add,remove,contains,toggle 等方法 |
| dataset | 对应元素的自定义属性 <p data-a = '1'></p>, 可写可读 p.dataset.a = '2 |
| innerHTML | 可写可读,改变某个节点的内容,读取时会把文本转为<, ,> 这种实体形式,innerHTML 插入的 script 会被处插入但不被执行,但是也有风险比如 var name = "<img src=x onerror=alert(1)>";el.innerHTML = name; |
| outerHTML | 返回包括自身的所有 HTML 代码, 赋值等于替换元素 |
| children | 子元素 HTMLCollection |
| firstElementChild, lastElementChild | --- |
| nextElementSibling, previousElementSibling | --- |
元素位置
| 属性 | 说明 |
|---|---|
| clienHeight,clienWidth | 返回元素的像素单位高度、宽度,只对块级元素生效,不包括 border, margin, 滚动条 |
| clentLeft, clientTop | 返回元素距离网页左边框和上边框的像素距离 |
| scrollHeight, scrollWidth | 返回元素总高度,包括溢出容器的部分,同样不包括border padding和滚动条,获取网页的总高度总宽度 document.body.scrollHeight |
| scrollLeft, scrollTop | scrollLeft 表示当前元素的水平滚动条向右侧滚动的像素数量,scrollTop属性表示当前元素的垂直滚动条向下滚动的像素数量 |
| offsetParent | 返回最靠近当前元素的非 static 定位的上层元素,许多偏移计算的基准都是这个offsetParent |
| offsetHeight, offsetWidth | 这两个属性都是只读属性,只比Element.clientHeight和Element.clientWidth多了边框的高度或宽度 |
| offsetLeft, offsetTop | 当前元素左上角相对于 offsetParent 的位移量 |
方法
属性操作
| 方法 | 说明 |
|---|---|
| getAttribute() | 读取某个属性的值 |
| getAttributeNames() | 返回当前元素的所有属性名 |
| setAttribute() | 写入属性值 |
| hasAttribute() | 某个属性是否存在 |
| hasAttributes() | 当前元素是否有属性 |
| removeAttribute() | 删除属性 |
选择器
| 方法 | 说明 |
|---|---|
| querySelector, querySelectorAll | --- |
| getElementsByClassName | --- |
| getElementsByTagName | --- |
| closest | 也是接受一个选择器,返回符合条件的最近父节点(包括自己) |
| matches | 判断是否符合该选择器 |
事件相关
| 方法 | 说明 |
|---|---|
| addEventListener | --- |
| removeEventListener | --- |
| dispatchEvent | --- |
| focus | --- |
| blur | --- |
| click | 模拟点击 |
位置相关
| 方法 | 说明 |
|---|---|
| scrollIntoView | 滚动浏览器页面,把该元素置于可见区域 |
| getBoundingClientRect | 获取元素的 x,y,height,width,left,right,top,bottom , 包括边框 |
插入相关
| 方法 | 说明 |
|---|---|
| insertAdjacentElement | --- |
| insertAdjacentHTML | --- |
| insertAdjacentText | --- |