学习教材为:https://wangdoc.com/javascript/dom/index.html
1 什么是DOM ?其作用是?
DOM 是 JavaScript 操作网页的接口,全称为“文档对象模型”(Document Object Model)。它的作用是将网页转为一个 JavaScript 对象,从而可以用脚本进行各种操作(比如增删内容)。
2 为什么说DOM 不是 JavaScript 语法的一部分?
DOM 只是一个接口规范,可以用各种语言实现。所以严格地说,DOM 不是 JavaScript 语法的一部分,但是 DOM 操作是 JavaScript 最常见的任务,离开了 DOM,JavaScript 就无法控制网页。另一方面,JavaScript 也是最常用于 DOM 操作的语言。
3 什么是节点(node)?其类型有哪些?
DOM 的最小组成单位叫做节点(node)。文档的树形结构(DOM 树),就是由各种不同类型的节点组成。每个节点可以看作是文档树的一片叶子。
节点的类型有七种。
- Document:整个文档树的顶层节点
- DocumentType:doctype标签(比如<!DOCTYPE html>)
- Element:网页的各种HTML标签(比如<body>、<a>等)
- Attr:网页元素的属性(比如class="right")
- Text:标签之间或标签包含的文本
- Comment:注释
- DocumentFragment:文档的片段
4 节点间的层级关系有哪些?
- 父节点关系(parentNode):直接的那个上级节点
- 子节点关系(childNodes):直接的下级节点
- 同级节点关系(sibling):拥有同一个父节点的节点
5 DOM 节点对象都有哪些属性?
- nodeType属性返回一个整数值,表示节点的类型。
- nodeName属性返回节点的名称。
- nodeValue属性返回一个字符串,表示当前节点本身的文本值,该属性可读写。
- textContent属性返回当前节点和它的所有后代节点的文本内容。
- baseURI属性返回一个字符串,表示当前网页的绝对路径。浏览器根据这个属性,计算网页上的相对路径的 URL。该属性为只读。
- Node.ownerDocument属性返回当前节点所在的顶层文档对象,即document对象。
- Node.nextSibling属性返回紧跟在当前节点后面的第一个同级节点。如果当前节点后面没有同级节点,则返回null。
- previousSibling属性返回当前节点前面的、距离最近的一个同级节点。如果当前节点前面没有同级节点,则返回null。
- parentNode属性返回当前节点的父节点。对于一个节点来说,它的父节点只可能是三种类型:元素节点(element)、文档节点(document)和文档片段节点(documentfragment)。
- parentElement属性返回当前节点的父元素节点。如果当前节点没有父节点,或者父节点类型不是元素节点,则返回null。
- firstChild属性返回当前节点的第一个子节点,如果当前节点没有子节点,则返回null。
- lastChild属性返回当前节点的最后一个子节点,如果当前节点没有子节点,则返回null。用法与firstChild属性相同。
- childNodes属性返回一个类似数组的对象(NodeList集合),成员包括当前节点的所有子节点。
- isConnected属性返回一个布尔值,表示当前节点是否在文档之中。
6 DOM 节点对象都有哪些方法?
- appendChild()方法接受一个节点对象作为参数,将其作为最后一个子节点,插入当前节点。该方法的返回值就是插入文档的子节点。
- hasChildNodes方法返回一个布尔值,表示当前节点是否有子节点。
- cloneNode方法用于克隆一个节点。它接受一个布尔值作为参数,表示是否同时克隆子节点。它的返回值是一个克隆出来的新节点。
- insertBefore方法用于将某个节点插入父节点内部的指定位置。
- removeChild方法接受一个子节点作为参数,用于从当前节点移除该子节点。返回值是移除的子节点。
- replaceChild方法用于将一个新的节点,替换当前节点的某一个子节点。
- contains方法返回一个布尔值,表示参数节点是否满足以下三个条件之一。
参数节点为当前节点。
参数节点为当前节点的子节点。
参数节点为当前节点的后代节点。 - compareDocumentPosition方法的用法,与contains方法完全一致,返回一个六个比特位的二进制值,表示参数节点与当前节点的关系。
- isEqualNode方法返回一个布尔值,用于检查两个节点是否相等。所谓相等的节点,指的是两个节点的类型相同、属性相同、子节点相同。
- normalize方法用于清理当前节点内部的所有文本节点(text)。它会去除空的文本节点,并且将毗邻的文本节点合并成一个,也就是说不存在空的文本节点,以及毗邻的文本节点。
- getRootNode()方法返回当前节点所在文档的根节点document,与ownerDocument属性的作用相同。
7 NodeList和HTMLCollection的区别?
NodeList可以包含各种类型的节点,HTMLCollection只能包含 HTML 元素节点。
8 类数组对象和数组的区别?相互如何转化?
可以使用length属性和forEach方法。但是,它不是数组,不能使用pop或push之类数组特有的方法。
// 转为数组
var children = document.body.childNodes;
var nodeArr = Array.prototype.slice.call(children);
9 ParentNode和ChildNode的区别?
ParentNode接口表示当前节点是一个父节点,提供一些处理子节点的方法。ChildNode接口表示当前节点是一个子节点,提供一些相关方法。
10 有哪些方法可以获取document对象?
- 正常的网页,直接使用document或window.document。
- iframe框架里面的网页,使用iframe节点的contentDocument属性。
- Ajax 操作返回的文档,使用XMLHttpRequest对象的responseXML属性。
- 内部节点的ownerDocument属性
11 document节点对象有哪些属性和方法?
属性
- document.defaultView属性返回document对象所属的window对象。如果当前文档不属于window对象,该属性返回null。
- 对于 HTML 文档来说,document对象一般有两个子节点。第一个子节点是document.doctype,指向<DOCTYPE>节点,即文档类型(Document Type Declaration,简写DTD)节点。HTML 的文档类型节点,一般写成<!DOCTYPE html>。如果网页没有声明 DTD,该属性返回null。
- document.documentElement属性返回当前文档的根元素节点(root)。它通常是document节点的第二个子节点,紧跟在document.doctype节点后面。HTML网页的该属性,一般是<html>节点。
- document.body属性指向<body>节点,document.head属性指向<head>节点。
这两个属性总是存在的,如果网页源码里面省略了<head>或<body>,浏览器会自动创建。另外,这两个属性是可写的,如果改写它们的值,相当于移除所有子节点。 - document.scrollingElement属性返回文档的滚动元素。也就是说,当文档整体滚动时,到底是哪个元素在滚动。
标准模式下,这个属性返回的文档的根元素document.documentElement(即<html>)。兼容(quirk)模式下,返回的是<body>元素,如果该元素不存在,返回null。 - document.activeElement属性返回获得当前焦点(focus)的 DOM 元素。通常,这个属性返回的是<input>、<textarea>、<select>等表单元素,如果当前没有焦点元素,返回<body>元素或null。
- document.fullscreenElement属性返回当前以全屏状态展示的 DOM 元素。如果不是全屏状态,该属性返回null。
- document.links属性返回当前文档所有设定了href属性的<a>及<area>节点。
- document.forms属性返回所有<form>表单节点。
- document.images属性返回页面所有<img>图片节点。
- document.embeds属性和document.plugins属性,都返回所有<embed>节点。
- document.scripts属性返回所有<script>节点。
- document.styleSheets属性返回文档内嵌或引入的样式表集合。
- document.documentURI属性和document.URL属性都返回一个字符串,表示当前文档的网址。不同之处是它们继承自不同的接口,documentURI继承自Document接口,可用于所有文档;URL继承自HTMLDocument接口,只能用于 HTML 文档。
- document.domain属性返回当前文档的域名,不包含协议和端口。比如,网页的网址是http://www.example.com:80/hello.html,那么document.domain属性就等于www.example.com。如果无法获取域名,该属性返回null。
document.domain基本上是一个只读属性,只有一种情况除外。次级域名的网页,可以把document.domain设为对应的上级域名。比如,当前域名是a.sub.example.com,则document.domain属性可以设置为sub.example.com,也可以设为example.com。修改后,document.domain相同的两个网页,可以读取对方的资源,比如设置的 Cookie。
另外,设置document.domain会导致端口被改成null。因此,如果通过设置document.domain来进行通信,双方网页都必须设置这个值,才能保证端口相同。 - Location对象是浏览器提供的原生对象,提供 URL 相关的信息和操作方法。通过window.location和document.location属性,可以拿到这个对象。
- document.lastModified属性返回一个字符串,表示当前文档最后修改的时间。不同浏览器的返回值,日期格式是不一样的。
- document.title属性返回当前文档的标题。默认情况下,返回<title>节点的值。但是该属性是可写的,一旦被修改,就返回修改后的值。
- document.characterSet属性返回当前文档的编码,比如UTF-8、ISO-8859-1等等。
- document.referrer属性返回一个字符串,表示当前文档的访问者来自哪里。
- document.dir返回一个字符串,表示文字方向。它只有两个可能的值:rtl表示文字从右到左,阿拉伯文是这种方式;ltr表示文字从左到右,包括英语和汉语在内的大多数文字采用这种方式。
- compatMode属性返回浏览器处理文档的模式,可能的值为BackCompat(向后兼容模式)和CSS1Compat(严格模式)。
- document.hidden属性返回一个布尔值,表示当前页面是否可见。如果窗口最小化、浏览器切换了 Tab,都会导致导致页面不可见,使得document.hidden返回true。
- document.visibilityState返回文档的可见状态。
- document.readyState属性返回当前文档的状态。
- document.cookie属性用来操作浏览器 Cookie。
- document.designMode属性控制当前文档是否可编辑。该属性只有两个值on和off,默认值为off。一旦设为on,用户就可以编辑整个文档的内容。
- document.currentScript属性只用在<script>元素的内嵌脚本或加载的外部脚本之中,返回当前脚本所在的那个 DOM 节点,即<script>元素的 DOM 节点。
- document.implementation属性返回一个DOMImplementation对象。该对象有三个方法,主要用于创建独立于当前文档的新的 Document 对象。
方法
- document.open方法清除当前文档所有内容,使得文档处于可写状态,
- document.write方法用于向当前文档写入内容。
- document.writeln方法与write方法完全一致,除了会在输出内容的尾部添加换行符。
- document.close方法用来关闭document.open()打开的文档
- document.querySelector方法接受一个 CSS 选择器作为参数,返回匹配该选择器的元素节点。如果有多个节点满足匹配条件,则返回第一个匹配的节点。如果没有发现匹配的节点,则返回null。
- document.querySelectorAll方法与querySelector用法类似,区别是返回一个NodeList对象,包含所有匹配给定选择器的节点。
- document.getElementsByTagName()方法搜索 HTML 标签名,返回符合条件的元素。它的返回值是一个类似数组对象(HTMLCollection实例),可以实时反映 HTML 文档的变化。如果没有任何匹配的元素,就返回一个空集。
- document.getElementsByClassName()方法返回一个类似数组的对象(HTMLCollection实例),包括了所有class名字符合指定条件的元素,元素的变化实时反映在返回结果中。
- document.getElementsByName()方法用于选择拥有name属性的 HTML 元素(比如<form>、<radio>、<img>、<frame>、<embed>和<object>等),返回一个类似数组的的对象(NodeList实例),因为name属性相同的元素可能不止一个。
- document.getElementById()方法返回匹配指定id属性的元素节点。如果没有发现匹配的节点,则返回null。
- document.elementFromPoint()方法返回位于页面指定位置最上层的元素节点。
- document.createElement方法用来生成元素节点,并返回该节点。
- document.createTextNode方法用来生成文本节点(Text实例),并返回该节点。它的参数是文本节点的内容。
- document.createAttribute方法生成一个新的属性节点(Attr实例),并返回它。
- document.createComment方法生成一个新的注释节点,并返回该节点。
- document.createDocumentFragment方法生成一个空的文档片段对象(DocumentFragment实例)。
- document.createEvent方法生成一个事件对象(Event实例),该对象可以被element.dispatchEvent方法使用,触发指定事件。
- document.hasFocus方法返回一个布尔值,表示当前文档之中是否有元素被激活或获得焦点。
- document.adoptNode方法将某个节点及其子节点,从原来所在的文档或DocumentFragment里面移除,归属当前document对象,返回插入后的新节点。插入的节点对象的ownerDocument属性,会变成当前的document对象,而parentNode属性是null。
- document.importNode方法则是从原来所在的文档或DocumentFragment里面,拷贝某个节点及其子节点,让它们归属当前document对象。拷贝的节点对象的ownerDocument属性,会变成当前的document对象,而parentNode属性是null。
- document.createNodeIterator方法返回一个子节点遍历器。
- document.createTreeWalker方法返回一个 DOM 的子树遍历器。它与document.createNodeIterator方法基本是类似的,区别在于它返回的是TreeWalker实例,后者返回的是NodeIterator实例。另外,它的第一个节点不是根节点。
- 如果document.designMode属性设为on,那么整个文档用户可编辑;如果元素的contenteditable属性设为true,那么该元素可编辑。这两种情况下,可以使用document.execCommand()方法,改变内容的样式,比如document.execCommand('bold')会使得字体加粗。
- document.queryCommandSupported()方法返回一个布尔值,表示浏览器是否支持document.execCommand()的某个命令。
- document.queryCommandEnabled()方法返回一个布尔值,表示当前是否可用document.execCommand()的某个命令。比如,bold(加粗)命令只有存在文本选中时才可用,如果没有选中文本,就不可用。
12 什么是Element节点对象?有哪些常用的属性和方法?
Element节点对象对应网页的 HTML 元素。每一个 HTML 元素,在 DOM 树上都会转化成一个Element节点对象(以下简称元素节点)。
13 属性操作的标准方法有哪些?
- getAttribute():读取某个属性的值
- getAttributeNames():返回当前元素的所有属性名
- setAttribute():写入属性值
- hasAttribute():某个属性是否存在
- hasAttributes():当前元素是否有属性
- removeAttribute():删除属性
14 如何获取文本节点?
Element.innerHTML属性返回一个字符串,等同于该元素包含的所有 HTML 代码。该属性可读写,常用来设置某个节点的内容。它能改写所有元素节点的内容,包括<HTML>和<body>元素。
15 有哪些操作 CSS 样式的方法?
- Element.hidden属性返回一个布尔值,表示当前元素的hidden属性,用来控制当前元素是否可见。该属性可读写。
16 什么是Mutation Observer API ?与事件有什么区别?
Mutation Observer API 用来监视 DOM 变动。DOM 的任何变动,比如节点的增减、属性的变动、文本内容的变动,这个 API 都可以得到通知。
概念上,它很接近事件,可以理解为 DOM 发生变动就会触发 Mutation Observer 事件。但是,它与事件有一个本质不同:事件是同步触发,也就是说,DOM 的变动立刻会触发相应的事件;Mutation Observer 则是异步触发,DOM 的变动并不会马上触发,而是要等到当前所有 DOM 操作都结束才触发。
17 MutationObserver 的实例方法有哪些?
- observe()方法用来启动监听,它接受两个参数。
- disconnect()方法用来停止观察。调用该方法后,DOM 再发生变动,也不会触发观察器。
- takeRecords()方法用来清除变动记录,即不再处理未处理的变动。该方法返回变动记录的数组。