DOM 是 JavaScript 操做网页的接口,全称为“文档对象模型”(Document Object Model)。它的做用是将网页转为一个 JavaScript 对象,从而能够用脚本进行各类操做(好比增删内容)。javascript
浏览器会根据 DOM 模型,将结构化文档(好比 HTML 和 XML)解析成一系列的节点,再由这些节点组成一个树状结构(DOM Tree)。全部的节点和最终的树状结构,都有规范的对外接口。css
DOM 只是一个接口规范,能够用各类语言实现。因此严格地说,DOM 不是 JavaScript 语法的一部分,可是 DOM 操做是 JavaScript 最多见的任务,离开了 DOM,JavaScript 就没法控制网页。另外一方面,JavaScript 也是最经常使用于 DOM 操做的语言。后面介绍的就是 JavaScript 对 DOM 标准的实现和用法。html
DOM 的最小组成单位叫作节点(node)。文档的树形结构(DOM 树),就是由各类不一样类型的节点组成。每一个节点能够看做是文档树的一片叶子。java
节点的类型有七种。node
Document
:整个文档树的顶层节点DocumentType
:doctype
标签(好比<!DOCTYPE html>
)Element
:网页的各类HTML标签(好比<body>
、<a>
等)Attribute
:网页元素的属性(好比class="right"
)Text
:标签之间或标签包含的文本Comment
:注释DocumentFragment
:文档的片断浏览器提供一个原生的节点对象Node
,上面这七种节点都继承了Node
,所以具备一些共同的属性和方法。jquery
一个文档的全部节点,按照所在的层级,能够抽象成一种树状结构。这种树状结构就是 DOM 树。数组
1.nodeType
属性返回一个整数值,表示节点的类型。浏览器
不一样节点的nodeType
属性值和对应的常量以下。bash
Node.DOCUMENT_NODE
Node.ELEMENT_NODE
Node.ATTRIBUTE_NODE
Node.TEXT_NODE
Node.DOCUMENT_FRAGMENT_NODE
Node.DOCUMENT_TYPE_NODE
Node.COMMENT_NODE
nodeName
属性返回节点的名称。cookie
// HTML 代码以下
// <div id="d1">hello world</div>
var div = document.getElementById('d1');
div.nodeName // "DIV"
复制代码
不一样节点的nodeName
属性值以下。
#document
#text
#document-fragment
#comment
nodeValue
属性返回一个字符串,表示当前节点自己的文本值,该属性可读写。
只有文本节点(text)、注释节点(comment)和属性节点(attr)有文本值,所以这三类节点的nodeValue
能够返回结果,其余类型的节点一概返回null
。
textContent
属性返回当前节点和它的全部后代节点的文本内容。(可读可写)
baseURI
属性返回一个字符串,表示当前网页的绝对路径。浏览器根据这个属性,计算网页上的相对路径的 URL。该属性为只读。
// 当前网页的网址为
// http://www.example.com/index.html
document.baseURI
// "http://www.example.com/index.html"
复制代码
该属性的值通常由当前网址的 URL(即window.location
属性)决定,可是可使用 HTML 的<base>
标签,改变该属性的值。
<base href="http://www.example.com/page.html">
复制代码
设置了之后,baseURI
属性就返回<base>
标签设置的值。
Node.ownerDocument
属性返回当前节点所在的顶层文档对象,即document
对象。
var d = p.ownerDocument;
d === document // true
复制代码
document
对象自己的ownerDocument
属性,返回null
。
parentNode
属性返回当前节点的父节点。对于一个节点来讲,它的父节点只多是三种类型:元素节点(element)、文档节点(document)和文档片断节点(documentfragment)。
parentElement
属性返回当前节点的父元素节点。若是当前节点没有父节点,或者父节点类型不是元素节点,则返回null
。
childNodes
属性返回一个相似数组的对象(NodeList
集合),成员包括当前节点的全部子节点。
isConnected
属性返回一个布尔值,表示当前节点是否在文档之中。
var test = document.createElement('p');
test.isConnected // false
document.body.appendChild(test);
test.isConnected // true
复制代码
hasChildNodes
方法返回一个布尔值,表示当前节点是否有子节点。
var foo = document.getElementById('foo');
if (foo.hasChildNodes()) {
foo.removeChild(foo.childNodes[0]);
}
复制代码
hasChildNodes
方法结合firstChild
属性和nextSibling
属性,能够遍历当前节点的全部后代节点。
function DOMComb(parent, callback) {
if (parent.hasChildNodes()) {
for (var node = parent.firstChild; node; node = node.nextSibling) {
DOMComb(node, callback);
}
}
callback(parent);
}
// 用法
DOMComb(document.body, console.log)
复制代码
cloneNode
方法用于克隆一个节点。它接受一个布尔值做为参数,表示是否同时克隆子节点。它的返回值是一个克隆出来的新节点。
var cloneUL = document.querySelector('ul').cloneNode(true);
复制代码
注意:
1.克隆一个节点,会拷贝该节点的全部属性,可是会丧失addEventListener
方法和on-
属性(即node.onclick = fn
),添加在这个节点上的事件回调函数。
2.克隆一个节点以后,DOM 有可能出现两个有相同id
属性(即id="xxx"
)的网页元素,这时应该修改其中一个元素的id
属性。若是原节点有name
属性,可能也须要修改。
3.该方法返回的节点不在文档之中,即没有任何父节点,必须使用诸如Node.appendChild
这样的方法添加到文档之中。
insertBefore
方法接受两个参数,第一个参数是所要插入的节点newNode
,第二个参数是父节点parentNode
内部的一个子节点referenceNode
。newNode
将插在referenceNode
这个子节点的前面。返回值是插入的新节点newNode
。
replaceChild
方法用于将一个新的节点,替换当前节点的某一个子节点。
var replacedNode = parentNode.replaceChild(newChild, oldChild);
复制代码
只能替换下一级子节点
contains
方法返回一个布尔值,表示参数节点是否知足如下三个条件之一。
isEqualNode
方法返回一个布尔值,用于检查两个节点是否相等。所谓相等的节点,指的是两个节点的类型相同、属性相同、子节点相同。
isSameNode
方法返回一个布尔值,表示两个节点是否为同一个节点
normalize
方法用于清理当前节点内部的全部文本节点(text)。它会去除空的文本节点,而且将毗邻的文本节点合并成一个,也就是说不存在空的文本节点,以及毗邻的文本节点。
该方法是Text.splitText
的逆方法,能够查看《Text 节点对象》一章,了解更多内容。
getRootNode()
方法返回当前节点所在文档的根节点document
,与ownerDocument
属性的做用相同。
节点都是单个对象,有时须要一种数据结构,可以容纳多个节点。DOM 提供两种节点集合,用于容纳多个节点:NodeList
和HTMLCollection
。
NodeList
实例是一个相似数组的对象,它的成员是节点对象。经过如下方法能够获得NodeList
实例。
Node.childNodes
document.querySelectorAll()
等节点搜索方法item
方法接受一个整数值做为参数,表示成员的位置,返回该位置上的成员。
document.body.childNodes.item(0)
复制代码
这三个方法都返回一个 ES6 的遍历器对象,能够经过for...of
循环遍历获取每个成员的信息。区别在于,keys()
返回键名的遍历器,values()
返回键值的遍历器,entries()
返回的遍历器同时包含键名和键值的信息。
var children = document.body.childNodes;
for (var key of children.keys()) {
console.log(key);
}
// 0
// 1
// 2
// ...
for (var value of children.values()) {
console.log(value);
}
// #text
// <script>
// ...
for (var entry of children.entries()) {
console.log(entry);
}
// Array [ 0, #text ]
// Array [ 1, <script> ]
// ...
复制代码
TMLCollection
是一个节点对象的集合,只能包含元素节点(element),不能包含其余类型的节点。它的返回值是一个相似数组的对象,可是与NodeList
接口不一样,HTMLCollection
没有forEach
方法,只能使用for
循环遍历。
返回HTMLCollection
实例的,主要是一些Document
对象的集合属性,好比document.links
、document.forms
、document.images
等。
若是元素节点有id
或name
属性,那么HTMLCollection
实例上面,可使用id
属性或name
属性引用该节点元素。若是没有对应的节点,则返回null
。
// HTML 代码以下
// <img id="pic" src="http://example.com/foo.jpg">
var pic = document.getElementById('pic');
document.images.pic === pic // true
复制代码
namedItem
方法的参数是一个字符串,表示id
属性或name
属性的值,返回对应的元素节点。若是没有对应的节点,则返回null
。
节点对象除了继承 Node 接口之外,还会继承其余接口。ParentNode
接口表示当前节点是一个父节点,提供一些处理子节点的方法。ChildNode
接口表示当前节点是一个子节点,提供一些相关方法。
remove
方法用于从父节点移除当前节点。
before
方法用于在当前节点的前面,插入一个或多个同级节点。二者拥有相同的父节点。
replaceWith
方法使用参数节点,替换当前节点。参数能够是元素节点,也能够是文本节点。
var span = document.createElement('span');
el.replaceWith(span);
复制代码
上面代码中,el
节点将被span
节点替换。
document
节点对象表明整个文档,每张网页都有本身的document
对象。
document
对象有不一样的办法能够获取。
document
或window.document
。iframe
框架里面的网页,使用iframe
节点的contentDocument
属性。XMLHttpRequest
对象的responseXML
属性。ownerDocument
属性。document
对象继承了EventTarget
接口、Node
接口、ParentNode
接口。这意味着,这些接口的方法均可以在document
对象上调用。除此以外,document
对象还有不少本身的属性和方法。
document.doctype
对于 HTML 文档来讲,document
对象通常有两个子节点。第一个子节点是document.doctype
document.documentElement
document.documentElement
属性返回当前文档的根元素节点(root)。即第二个节点
document.body,document.head
能够直接获取body,head
document.scrollingElement
document.scrollingElement
属性返回文档的滚动元素。也就是说,当文档总体滚动时,究竟是哪一个元素在滚动。
标准模式下,这个属性返回的文档的根元素document.documentElement
(即<html>
)。兼容(quirk)模式下,返回的是<body>
元素,若是该元素不存在,返回null
。
// 页面滚动到浏览器顶部
document.scrollingElement.scrollTop = 0;
复制代码
document.activeElement
document.activeElement
属性返回得到当前焦点(focus)的 DOM 元素。一般,这个属性返回的是<input>
、<textarea>
、<select>
等表单元素,若是当前没有焦点元素,返回<body>
元素或null
。
document.links
document.links
属性返回当前文档全部设定了href
属性的<a>
及<area>
节点。
document.forms
document.forms
属性返回全部<form>
表单节点。
document.images
document.images
属性返回页面全部<img>
图片节点。
document.embeds,document.plugins
document.embeds
属性和document.plugins
属性,都返回全部<embed>
节点。
document.scripts
document.scripts
属性返回全部<script>
节点。
document.styleSheets
document.styleSheets
属性返回文档内嵌或引入的样式表集合,详细介绍请看《CSS 对象模型》一章。
总结:以上的集合属性返回的都是HTMLCollection
实例
document.documentURI,document.URL
document.documentURI
属性和document.URL
属性都返回一个字符串,表示当前文档的网址。不一样之处是它们继承自不一样的接口,documentURI
继承自Document
接口,可用于全部文档;URL
继承自HTMLDocument
接口,只能用于 HTML 文档。
document.domain
document.domain
属性返回当前文档的域名,不包含协议和接口。
document.location
Location
对象是浏览器提供的原生对象,提供 URL 相关的信息和操做方法。经过window.location
和document.location
属性,能够拿到这个对象。
document.lastModified
document.lastModified
属性返回一个字符串,表示当前文档最后修改的时间。不一样浏览器的返回值,日期格式是不同的。
document.title
document.title
属性返回当前文档的标题。
document.characterSet
document.characterSet
属性返回当前文档的编码,好比UTF-8
、ISO-8859-1
等等
document.referrer
document.referrer
属性返回一个字符串,表示当前文档的访问者来自哪里。
document.dir
document.dir
返回一个字符串,表示文字方向。
<html dir="rtl" lang="zh" i18n-processed="">
document.dir //"rtl"
复制代码
document.compatMode
compatMode
属性返回浏览器处理文档的模式,可能的值为BackCompat
(向后兼容模式)和CSS1Compat
(严格模式)。
通常来讲,若是网页代码的第一行设置了明确的DOCTYPE
(好比<!doctype html>
),document.compatMode
的值都为CSS1Compat
。
1.document.hidden
document.hidden
属性返回一个布尔值,表示当前页面是否可见。若是窗口最小化、浏览器切换了 Tab,都会致使致使页面不可见,使得document.hidden
返回true
。
2.document.visibilityState
document.visibilityState
返回文档的可见状态。
它的值有四种可能。
visible
:页面可见。注意,页面多是部分可见,即不是焦点窗口,前面被其余窗口部分挡住了。hidden
:页面不可见,有可能窗口最小化,或者浏览器切换到了另外一个 Tab。prerender
:页面处于正在渲染状态,对于用户来讲,该页面不可见。unloaded
:页面从内存里面卸载了。
这个属性能够用在页面加载时,防止加载某些资源;或者页面不可见时,停掉一些页面功能。
3.document.readyState
document.readyState
属性返回当前文档的状态,共有三种可能的值。
loading
:加载 HTML 代码阶段(还没有完成解析)interactive
:加载外部资源阶段complete
:加载完成这个属性变化的过程以下。
document.readyState
属性等于loading
。<script>
元素,而且没有async
或defer
属性,就暂停解析,开始执行脚本,这时document.readyState
属性仍是等于loading
。document.readyState
属性变成interactive
。document.readyState
属性变成complete
。document.cookie
属性用来操做浏览器 Cookie
document.designMode
属性控制当前文档是否可编辑。该属性只有两个值on
和off
,默认值为off
。一旦设为on
,用户就能够编辑整个文档的内容。
document.implementation
属性返回一个DOMImplementation
对象。该对象有三个方法,主要用于建立独立于当前文档的新的 Document 对象。
DOMImplementation.createDocument()
:建立一个 XML 文档。DOMImplementation.createHTMLDocument()
:建立一个 HTML 文档。DOMImplementation.createDocumentType()
:建立一个 DocumentType 对象。下面是建立 HTML 文档的例子。
var doc = document.implementation.createHTMLDocument('Title');
var p = doc.createElement('p');
p.innerHTML = 'hello world';
doc.body.appendChild(p);
document.replaceChild(
doc.documentElement,
document.documentElement
);
复制代码
上面代码中,第一步生成一个新的 HTML 文档doc
,而后用它的根元素document.documentElement
替换掉document.documentElement
。这会使得当前文档的内容所有消失,变成hello world
。
document.open
方法清除当前文档全部内容,使得文档处于可写状态,供document.write
方法写入内容。
document.write
方法用于向当前文档写入内容。
在网页的首次渲染阶段,只要页面没有关闭写入(即没有执行document.close()
),document.write
写入的内容就会追加在已有内容的后面。
若是页面已经解析完成(DOMContentLoaded
事件发生以后),再调用write
方法,它会先调用open
方法,擦除当前文档全部内容,而后再写入。
若是在页面渲染过程当中调用write
方法,并不会自动调用open
方法。(能够理解成,open
方法已调用,但close
方法还未调用。)
document.writeln
方法与write
方法彻底一致,除了会在输出内容的尾部添加换行符
document.elementFromPoint
方法返回位于页面指定位置最上层的元素节点。
var element = document.elementFromPoint(50, 50);
复制代码
上面代码选中在(50, 50)
这个坐标位置的最上层的那个 HTML 元素。
document.elementsFromPoint()
返回一个数组,成员是位于指定坐标(相对于视口)的全部元素。
document.caretRangeFromPoint
方法返回位于页面指定位置最上层的Range对象。
document.createTextNode
方法用来生成文本节点(Text
实例),并返回该节点。它的参数是文本节点的内容。
var newDiv = document.createElement('div');
var newContent = document.createTextNode('Hello');
newDiv.appendChild(newContent);
复制代码
上面代码新建一个div
节点和一个文本节点,而后将文本节点插入div
节点。
这个方法能够确保返回的节点,被浏览器看成文本渲染,而不是看成 HTML 代码渲染。所以,能够用来展现用户的输入,避免 XSS 攻击。
document.createAttribute
方法生成一个新的属性节点(Attr
实例),并返回它。
document.createAttribute
方法生成一个新的属性节点(Attr
实例),并返回它。
var attribute = document.createAttribute(name);
复制代码
document.createAttribute
方法的参数name
,是属性的名称。
var node = document.getElementById('div1');
var a = document.createAttribute('my_attrib');
a.value = 'newVal';
node.setAttributeNode(a);
// 或者
node.setAttribute('my_attrib', 'newVal');
复制代码
document.createComment
方法生成一个新的注释节点,并返回该节点。
var CommentNode = document.createComment(data);
复制代码
document.createComment
方法的参数是一个字符串,会成为注释节点的内容。
document.createDocumentFragment
方法生成一个空的文档片断对象(DocumentFragment
实例)。
var docFragment = document.createDocumentFragment();
复制代码
DocumentFragment
是一个存在于内存的 DOM 片断,不属于当前文档,经常用来生成一段较复杂的 DOM 结构,而后再插入当前文档。这样作的好处在于,由于DocumentFragment
不属于当前文档,对它的任何改动,都不会引起网页的从新渲染,比直接修改当前文档的 DOM 有更好的性能表现。
var docfrag = document.createDocumentFragment();
[1, 2, 3, 4].forEach(function (e) {
var li = document.createElement('li');
li.textContent = e;
docfrag.appendChild(li);
});
var element = document.getElementById('ul');
element.appendChild(docfrag);
复制代码
上面代码中,文档片段docfrag
包含四个<li>
节点,这些子节点被一次性插入了当前文档。
document.createEvent
方法生成一个事件对象(Event
实例),该对象能够被element.dispatchEvent
方法使用,触发指定事件。
var event = document.createEvent(type);
复制代码
document.createEvent
方法的参数是事件类型,好比UIEvents
、MouseEvents
、MutationEvents
、HTMLEvents
。
var event = document.createEvent('Event');
event.initEvent('build', true, true);
document.addEventListener('build', function (e) {
console.log(e.type); // "build"
}, false);
document.dispatchEvent(event);
复制代码
上面代码新建了一个名为build
的事件实例,而后触发该事件。
这三个方法用于处理document
节点的事件。它们都继承自EventTarget
接口,详细介绍参见《EventTarget 接口》一章。
// 添加事件监听函数
document.addEventListener('click', listener, false);
// 移除事件监听函数
document.removeEventListener('click', listener, false);
// 触发事件
var event = new Event('click');
document.dispatchEvent(event);
复制代码
document.hasFocus
方法返回一个布尔值,表示当前文档之中是否有元素被激活或得到焦点。
document.adoptNode
方法将某个节点及其子节点,从原来所在的文档或DocumentFragment
里面移除,归属当前document
对象,返回插入后的新节点。(返回DocumentFragment
里面移除的节点)
document.importNode
方法则是从原来所在的文档或DocumentFragment
里面,拷贝某个节点及其子节点,让它们归属当前document
对象。
var node = document.importNode(externalNode, deep);
复制代码
document.createNodeIterator
方法返回一个子节点遍历器。
var nodeIterator = document.createNodeIterator(
document.body,
NodeFilter.SHOW_ELEMENT
);
复制代码
document.createNodeIterator
方法第一个参数为所要遍历的根节点,第二个参数为所要遍历的节点类型,这里指定为元素节点(NodeFilter.SHOW_ELEMENT
)。几种主要的节点类型写法以下。
document.createNodeIterator
方法返回一个“遍历器”对象(NodeFilter
实例)。该实例的nextNode()
方法和previousNode()
方法,能够用来遍历全部子节点。
document.createTreeWalker
方法返回一个 DOM 的子树遍历器。它与document.createNodeIterator
方法基本是相似的,区别在于它返回的是TreeWalker
实例,后者返回的是NodeIterator
实例。另外,它的第一个节点不是根节点。
document.createTreeWalker
方法的第一个参数是所要遍历的根节点,第二个参数指定所要遍历的节点类型(与document.createNodeIterator
方法的第二个参数相同)。
var treeWalker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_ELEMENT
);
var nodeList = [];
while(treeWalker.nextNode()) {
nodeList.push(treeWalker.currentNode);
}
复制代码
若是document.designMode
属性设为on
,那么整个文档用户可编辑;若是元素的contenteditable
属性设为true
,那么该元素可编辑。这两种状况下,可使用document.execCommand()
方法,改变内容的样式。
该方法接受三个参数。
command
:字符串,表示所要实施的样式。showDefaultUI
:布尔值,表示是否要使用默认的用户界面,建议老是设为false
。input
:字符串,表示该样式的辅助内容,好比生成超级连接时,这个参数就是所要连接的网址。若是第二个参数设为true
,那么浏览器会弹出提示框,要求用户在提示框输入该参数。可是,不是全部浏览器都支持这样作,为了兼容性,仍是须要本身部署获取这个参数的方式。document.execCommand()
方法能够执行的样式改变有不少种,下面是其中的一些:bold、insertLineBreak、selectAll、createLink、insertOrderedList、subscript、delete、insertUnorderedList、superscript、formatBlock、insertParagraph、undo、forwardDelete、insertText、unlink、insertImage、italic、unselect、insertHTML、redo。这些值均可以用做第一个参数,它们的含义不难从字面上看出来。
document.queryCommandEnabled()
方法返回一个布尔值,表示浏览器是否容许使用这个方法。
document.queryCommandSupported()
方法返回一个布尔值,表示当前是否可用某种样式改变。
这个方法指向window.getSelection()
,参见window
对象一节的介绍。
document.querySelector(),document.querySelectorAll()
document.getElementsByTagName()
document.getElementsByClassName()
document.getElementsByName()
Element
节点对象对应网页的 HTML 元素。每个 HTML 元素,在 DOM 树上都会转化成一个Element
节点对象(如下简称元素节点)。
Element
对象继承了Node
接口,所以Node
的属性和方法在Element
对象都存在。
Element.id
Element.tagName
Element.dir
Element.dir
属性用于读写当前元素的文字方向,多是从左到右("ltr"
),也多是从右到左("rtl"
)。
Element.accessKey
Element.accessKey
属性用于读写分配给当前元素的快捷键。
Element.accessKey 属性不多使用,由于它很容易与现代浏览器自带的快捷键冲突。为了解决这个问题,浏览器约定accessKey键与特定按键一块儿按(好比 Alt + accessKey)来生效快捷键行为。*
// HTML 代码以下
// <button accesskey="h" id="btn">点击</button>
var btn = document.getElementById('btn');
btn.accessKey // "h"
复制代码
Element.draggable
Element.draggable
属性返回一个布尔值,表示当前元素是否可拖动。该属性可读写。
Element.lang
Element.lang
属性返回当前元素的语言设置。该属性可读写。
Element.title
Element.hidden
Element.hidden
属性返回一个布尔值,表示当前元素的hidden
属性,用来控制当前元素是否可见。该属性可读写。
该属性与 CSS 设置是互相独立的
CSS 对这个元素可见性的设置,Element.hidden
并不能反映出来。也就是说,这个属性并不能用来判断当前元素的实际可见性。
CSS 的设置高于Element.hidden
。若是 CSS 指定了该元素不可见(display: none
)或可见(display: hidden
),那么Element.hidden
并不能改变该元素实际的可见性。换言之,这个属性只在 CSS 没有明确设定当前元素的可见性时才有效。
Element.contentEditable,Element.isContentEditable
HTML 元素能够设置contentEditable
属性,使得元素的内容能够编辑。
Element.attributes
Element.className,Element.classList
上面代码中,className
属性返回一个空格分隔的字符串,而classList
属性指向一个相似数组的对象,该对象的length
属性(只读)返回当前元素的class
数量。
classList
对象有下列方法。
add()
:增长一个 class。remove()
:移除一个 class。contains()
:检查当前元素是否包含某个 class。toggle()
:将某个 class 移入或移出当前元素。item()
:返回指定索引位置的 class。toString()
:将 class 的列表转为字符串。getAttribute()
:读取某个属性的值getAttributeNames()
:返回当前元素的全部属性名setAttribute()
:写入属性值hasAttribute()
:某个属性是否存在hasAttributes()
:当前元素是否有属性removeAttribute()
:删除属性Element.closest
方法接受一个 CSS 选择器做为参数,返回匹配该选择器的、最接近当前节点的一个祖先节点(包括当前节点自己)。若是没有任何节点匹配 CSS 选择器,则返回null
。
div03.closest("#div-02") // div-02
div03.closest("div div") // div-03
div03.closest("article > div") //div-01
div03.closest(":not(div)") // article
复制代码
和jquery操做同样
Element.matches
方法返回一个布尔值,表示当前元素是否匹配给定的 CSS 选择器。
el.matches('.someClass') //样式包含someClass 返回true
document.querySelector('input').matches('[accessKey]') //包含属性accessKey 返回true
复制代码
Element.scrollIntoView
方法滚动当前元素,进入浏览器的可见区域,相似于设置window.location.hash
的效果。
el.scrollIntoView(); // 等同于el.scrollIntoView(true)
el.scrollIntoView(false);
复制代码
面代码中,getBoundingClientRect
方法返回的rect
对象,具备如下属性(所有为只读)。
x
:元素左上角相对于视口的横坐标y
:元素左上角相对于视口的纵坐标height
:元素高度width
:元素宽度left
:元素左上角相对于视口的横坐标,与x
属性相等right
:元素右边界相对于视口的横坐标(等于x + width
)top
:元素顶部相对于视口的纵坐标,与y
属性相等bottom
:元素底部相对于视口的纵坐标(等于y + height
)因为元素相对于视口(viewport)的位置,会随着页面滚动变化,所以表示位置的四个属性值,都不是固定不变的。若是想获得绝对位置,能够将left
属性加上window.scrollX
,top
属性加上window.scrollY
。
上面代码是一个行内元素<span>
,若是它在页面上占据三行,getClientRects
方法返回的对象就有三个成员,若是它在页面上占据一行,getClientRects
方法返回的对象就只有一个成员。
Element.insertAdjacentElement
方法在相对于当前元素的指定位置,插入一个新的节点。该方法返回被插入的节点,若是插入失败,返回null
。
element.insertAdjacentElement(position, element);
复制代码
第一个参数只能够取以下的值。
beforebegin
:当前元素以前afterbegin
:当前元素内部的第一个子节点前面beforeend
:当前元素内部的最后一个子节点后面afterend
:当前元素以后HTML 元素包括标签名和若干个键值对,这个键值对就称为“属性”(attribute)。
属性自己是一个对象(Attr
对象),可是实际上,这个对象极少使用。通常都是经过元素节点对象(HTMlElement
对象)来操做属性。本章介绍如何操做这些属性。
元素节点提供六个方法,用来操做属性。
getAttribute()
getAttributeNames()
setAttribute()
hasAttribute()
hasAttributes()
removeAttribute()
有时,须要在HTML元素上附加数据,供 JavaScript 脚本使用。更好的解决方法是,使用标准提供的data-*
属性。能够添加复杂的数据。
文本节点(Text
)表明元素节点(Element
)和属性节点(Attribute
)的文本内容。若是一个节点只包含一段文本,那么它就有一个文本子节点,表明该节点的文本内容。
一般咱们使用父节点的firstChild
、nextSibling
等属性获取文本节点,或者使用Document
节点的createTextNode
方法创造一个文本节点。
1.Text 节点的属性
data
属性等同于nodeValue
属性,用来设置或读取文本节点的内容。
2.Text 节点的方法
appendData(),deleteData(),insertData(),replaceData(),subStringData()
div.setAttribute(
'style',
'background-color:red;' + 'border:1px solid black;'
);
复制代码
CSSStyleDeclaration 接口用来操做元素的样式。三个地方部署了这个接口。
style
属性(Element.style
)CSSStyle
实例的style
属性window.getComputedStyle()
的返回值个对象所包含的属性与 CSS 规则一一对应,可是名字须要改写,好比background-color
写成backgroundColor
。改写的规则是将横杠从 CSS 属性名中去除,而后将横杠后的第一个字母大写。若是 CSS 属性名是 JavaScript 保留字,则规则名以前须要加上字符串css
,好比float
写成cssFloat
。
注意,该对象的属性值都是字符串,设置时必须包括单位,可是不含规则结尾的分号。好比,divStyle.width
不能写为100
,而要写为100px
。
CSSStyleDeclaration.cssText
CSSStyleDeclaration.length
CSSStyleDeclaration.length
属性返回一个整数值,表示当前规则包含多少条样式声明。
CSSStyleDeclaration.parentRule
CSSStyleDeclaration.parentRule
属性返回当前规则所属的那个样式块(CSSRule 实例)。若是不存在所属的样式块,该属性返回null
。
该属性只读,且只在使用 CSSRule 接口时有意义。
var declaration = document.styleSheets[0].rules[0].style;
declaration.parentRule === document.styleSheets[0].rules[0]
// true
复制代码
SSStyleDeclaration.getPropertyPriority
方法接受 CSS 样式的属性名做为参数,返回一个字符串,表示有没有设置important
优先级。若是有就返回important
,不然返回空字符串。
style.getPropertyPriority('margin') // "important"
style.getPropertyPriority('color') // ""
复制代码
CSSStyleDeclaration.getPropertyValue
方法接受 CSS 样式属性名做为参数,返回一个字符串,表示该属性的属性值。
CSSStyleDeclaration.item
方法接受一个整数值做为参数,返回该位置的 CSS 属性名。
// HTML 代码为
// <div id="myDiv" style="color: red; background-color: white;"/>
var style = document.getElementById('myDiv').style;
style.item(0) // "color"
style.item(1) // "background-color"
复制代码
CSSStyleDeclaration.removeProperty
方法接受一个属性名做为参数,在 CSS 规则里面移除这个属性,返回这个属性原来的值。
CSSStyleDeclaration.setProperty
方法用来设置新的 CSS 属性。该方法没有返回值。
该方法能够接受三个参数。
important
,表示 CSS 规则里面的!important
。这种侦测方法能够写成一个函数。
function isPropertySupported(property) {
if (property in document.body.style) return true;
var prefixes = ['Moz', 'Webkit', 'O', 'ms', 'Khtml'];
var prefProperty = property.charAt(0).toUpperCase() + property.substr(1);
for(var i = 0; i < prefixes.length; i++){
if((prefixes[i] + prefProperty) in document.body.style) return true;
}
return false;
}
isPropertySupported('background-clip')
// true
复制代码
CSS.escape
方法用于转义 CSS 选择器里面的特殊字符。
<div id="foo#bar">
document.querySelector('#' + CSS.escape('foo#bar'))
复制代码
CSS.supports
方法返回一个布尔值,表示当前环境是否支持某一句 CSS 规则。
它的参数有两种写法,一种是第一个参数是属性名,第二个参数是属性值;另外一种是整个参数就是一行完整的 CSS 语句。
window.getComputedStyle
方法,就用来返回浏览器计算后获得的最终规则。它接受一个节点对象做为参数,返回一个 CSSStyleDeclaration 实例,包含了指定节点的最终样式信息。所谓“最终样式信息”,指的是各类 CSS 规则叠加后的结果。
var div = document.querySelector('div');
var styleObj = window.getComputedStyle(div);
styleObj.backgroundColor
复制代码
上面代码中,获得的背景色就是div
元素真正的背景色。
StyleSheet
接口表明网页的一张样式表,包括<link>
元素加载的样式表和<style>
元素内嵌的样式表。
获取StyleSheet实例
var sheets = document.styleSheets;
var sheet = document.styleSheets[0];
sheet instanceof StyleSheet // true
复制代码
StyleSheet实例的cssRules属性指向的就是CSSRuleList实例
CSSRule实例组成CSSRuleList实例
若是一条 CSS 规则是普通的样式规则(不含特殊的 CSS 命令),那么除了 CSSRule 接口,它还部署了 CSSStyleRule 接口。
若是一条 CSS 规则是@media
代码块,那么它除了 CSSRule 接口,还部署了 CSSMediaRule 接口。
具体参考文档:wangdoc.com/javascript/…
Mutation Observer API 用来监视 DOM 变更。DOM 的任何变更,好比节点的增减、属性的变更、文本内容的变更,这个 API 均可以获得通知。
概念上,它很接近事件,能够理解为 DOM 发生变更就会触发 Mutation Observer 事件。可是,它与事件有一个本质不一样:事件是同步触发,也就是说,DOM 的变更马上会触发相应的事件;Mutation Observer 则是异步触发,DOM 的变更并不会立刻触发,而是要等到当前全部 DOM 操做都结束才触发。
Mutation Observer 有如下特色。