一.概述
1.DOM
DOM 是 JavaScript 操作网页的接口,全称为“文档对象模型”(Document Object Model)。它的作用是将网页转为一个 JavaScript 对象,从而可以用脚本进行各种操作(比如增删内容)。
浏览器会根据 DOM 模型,将结构化文档(比如 HTML 和 XML)解析成一系列的节点,再由这些节点组成一个树状结构(DOM Tree)。所有的节点和最终的树状结构,都有规范的对外接口。
DOM 只是一个接口规范,可以用各种语言实现。所以严格地说,DOM 不是 JavaScript 语法的一部分,但是 DOM 操作是 JavaScript 最常见的任务,离开了 DOM,JavaScript 就无法控制网页。另一方面,JavaScript 也是最常用于 DOM 操作的语言。后面介绍的就是 JavaScript 对 DOM 标准的实现和用法。
2.节点
DOM 的最小组成单位叫做节点(node)。文档的树形结构(DOM 树),就是由各种不同类型的节点组成。每个节点可以看作是文档树的一片叶子。
节点的类型有七种。
Document:整个文档树的顶层节点DocumentType:doctype标签(比如<!DOCTYPE html>)Element:网页的各种HTML标签(比如<body>、<a>等)Attribute:网页元素的属性(比如class="right")Text:标签之间或标签包含的文本Comment:注释DocumentFragment:文档的片段
浏览器提供一个原生的节点对象Node,上面这七种节点都继承了Node,因此具有一些共同的属性和方法。
3.节点树
一个文档的所有节点,按照所在的层级,可以抽象成一种树状结构。这种树状结构就是 DOM 树。
二.Node 接口
1.属性
1.Node.prototype.nodeType
1.nodeType属性返回一个整数值,表示节点的类型。
不同节点的nodeType属性值和对应的常量如下。
- 文档节点(document):9,对应常量
Node.DOCUMENT_NODE - 元素节点(element):1,对应常量
Node.ELEMENT_NODE - 属性节点(attr):2,对应常量
Node.ATTRIBUTE_NODE - 文本节点(text):3,对应常量
Node.TEXT_NODE - 文档片断节点(DocumentFragment):11,对应常量
Node.DOCUMENT_FRAGMENT_NODE - 文档类型节点(DocumentType):10,对应常量
Node.DOCUMENT_TYPE_NODE - 注释节点(Comment):8,对应常量
Node.COMMENT_NODE
2.Node.prototype.nodeName
nodeName属性返回节点的名称。
// HTML 代码如下
// <div id="d1">hello world</div>
var div = document.getElementById('d1');
div.nodeName // "DIV"
不同节点的nodeName属性值如下。
- 文档节点(document):
#document - 元素节点(element):大写的标签名
- 属性节点(attr):属性的名称
- 文本节点(text):
#text - 文档片断节点(DocumentFragment):
#document-fragment - 文档类型节点(DocumentType):文档的类型
- 注释节点(Comment):
#comment
3.Node.prototype.nodeValue
nodeValue属性返回一个字符串,表示当前节点本身的文本值,该属性可读写。
只有文本节点(text)、注释节点(comment)和属性节点(attr)有文本值,因此这三类节点的nodeValue可以返回结果,其他类型的节点一律返回null。
4.Node.prototype.textContent
textContent属性返回当前节点和它的所有后代节点的文本内容。(可读可写)
5. Node.prototype.baseURI
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>标签设置的值。
6.Node.prototype.ownerDocument
Node.ownerDocument属性返回当前节点所在的顶层文档对象,即document对象。
var d = p.ownerDocument;
d === document // true
document对象本身的ownerDocument属性,返回null。
7.Node.prototype.parentNode
parentNode属性返回当前节点的父节点。对于一个节点来说,它的父节点只可能是三种类型:元素节点(element)、文档节点(document)和文档片段节点(documentfragment)。
8.Node.prototype.parentElement
parentElement属性返回当前节点的父元素节点。如果当前节点没有父节点,或者父节点类型不是元素节点,则返回null。
9.Node.prototype.childNodes
childNodes属性返回一个类似数组的对象(NodeList集合),成员包括当前节点的所有子节点。
10.Node.prototype.isConnected
isConnected属性返回一个布尔值,表示当前节点是否在文档之中。
var test = document.createElement('p');
test.isConnected // false
document.body.appendChild(test);
test.isConnected // true
2.方法
1.Node.prototype.hasChildNodes()
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)
2.Node.prototype.cloneNode()
cloneNode方法用于克隆一个节点。它接受一个布尔值作为参数,表示是否同时克隆子节点。它的返回值是一个克隆出来的新节点。
var cloneUL = document.querySelector('ul').cloneNode(true);
注意:
1.克隆一个节点,会拷贝该节点的所有属性,但是会丧失addEventListener方法和on-属性(即node.onclick = fn),添加在这个节点上的事件回调函数。
2.克隆一个节点之后,DOM 有可能出现两个有相同id属性(即id="xxx")的网页元素,这时应该修改其中一个元素的id属性。如果原节点有name属性,可能也需要修改。
3.该方法返回的节点不在文档之中,即没有任何父节点,必须使用诸如Node.appendChild这样的方法添加到文档之中。
3.Node.prototype.insertBefore()
insertBefore方法接受两个参数,第一个参数是所要插入的节点newNode,第二个参数是父节点parentNode内部的一个子节点referenceNode。newNode将插在referenceNode这个子节点的前面。返回值是插入的新节点newNode。
4.Node.prototype.replaceChild()
replaceChild方法用于将一个新的节点,替换当前节点的某一个子节点。
var replacedNode = parentNode.replaceChild(newChild, oldChild);
只能替换下一级子节点
5.Node.prototype.contains()
contains方法返回一个布尔值,表示参数节点是否满足以下三个条件之一。
- 参数节点为当前节点。
- 参数节点为当前节点的子节点。
- 参数节点为当前节点的后代节点。
6.Node.prototype.isEqualNode(),Node.prototype.isSameNode()
isEqualNode方法返回一个布尔值,用于检查两个节点是否相等。所谓相等的节点,指的是两个节点的类型相同、属性相同、子节点相同。
isSameNode方法返回一个布尔值,表示两个节点是否为同一个节点
7.Node.prototype.normalize()
normalize方法用于清理当前节点内部的所有文本节点(text)。它会去除空的文本节点,并且将毗邻的文本节点合并成一个,也就是说不存在空的文本节点,以及毗邻的文本节点。
该方法是Text.splitText的逆方法,可以查看《Text 节点对象》一章,了解更多内容。
8.Node.prototype.getRootNode()
getRootNode()方法返回当前节点所在文档的根节点document,与ownerDocument属性的作用相同。
三.NodeList 接口,HTMLCollection 接口
节点都是单个对象,有时需要一种数据结构,能够容纳多个节点。DOM 提供两种节点集合,用于容纳多个节点:NodeList和HTMLCollection。
1.NodeList
NodeList实例是一个类似数组的对象,它的成员是节点对象。通过以下方法可以得到NodeList实例。
Node.childNodesdocument.querySelectorAll()等节点搜索方法
方法
1.NodeList.prototype.item()
item方法接受一个整数值作为参数,表示成员的位置,返回该位置上的成员。
document.body.childNodes.item(0)
2.NodeList.prototype.keys(),NodeList.prototype.values(),NodeList.prototype.entries()
这三个方法都返回一个 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> ]
// ...
2.HTMLCollection
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
方法
1.HTMLCollection.prototype.namedItem()
namedItem方法的参数是一个字符串,表示id属性或name属性的值,返回对应的元素节点。如果没有对应的节点,则返回null。
四.ParentNode 接口,ChildNode 接口
节点对象除了继承 Node 接口以外,还会继承其他接口。ParentNode接口表示当前节点是一个父节点,提供一些处理子节点的方法。ChildNode接口表示当前节点是一个子节点,提供一些相关方法。
1.ParentNode有对子节点操作的方法
- ParentNode.append(),ParentNode.prepend()可以添加文本;appendChild()插入node对象这只是简单的插入应用
2.ChildNode有对自身操作的方法
1.ChildNode.remove()
remove方法用于从父节点移除当前节点。
2.ChildNode.before(),ChildNode.after()
before方法用于在当前节点的前面,插入一个或多个同级节点。两者拥有相同的父节点。
3.ChildNode.replaceWith()
replaceWith方法使用参数节点,替换当前节点。参数可以是元素节点,也可以是文本节点。
var span = document.createElement('span');
el.replaceWith(span);
上面代码中,el节点将被span节点替换。
五.Document 节点
document节点对象代表整个文档,每张网页都有自己的document对象。
document对象有不同的办法可以获取。
- 正常的网页,直接使用
document或window.document。 iframe框架里面的网页,使用iframe节点的contentDocument属性。- Ajax 操作返回的文档,使用
XMLHttpRequest对象的responseXML属性。 - 内部节点的
ownerDocument属性。
document对象继承了EventTarget接口、Node接口、ParentNode接口。这意味着,这些接口的方法都可以在document对象上调用。除此之外,document对象还有很多自己的属性和方法。
1.属性
1.快捷方式属性
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。
2.节点集合属性
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实例
3.文档静态信息属性
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。
4.文档状态属性
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:加载完成
这个属性变化的过程如下。
- 浏览器开始解析 HTML 文档,
document.readyState属性等于loading。 - 浏览器遇到 HTML 文档中的
<script>元素,并且没有async或defer属性,就暂停解析,开始执行脚本,这时document.readyState属性还是等于loading。 - HTML 文档解析完成,
document.readyState属性变成interactive。 - 浏览器等待图片、样式表、字体文件等外部资源加载完成,一旦全部加载完成,
document.readyState属性变成complete。
5.document.cookie
document.cookie属性用来操作浏览器 Cookie
6.document.designMode
document.designMode属性控制当前文档是否可编辑。该属性只有两个值on和off,默认值为off。一旦设为on,用户就可以编辑整个文档的内容。
7.document.implementation
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。
2.方法
1.document.open(),document.close()
document.open方法清除当前文档所有内容,使得文档处于可写状态,供document.write方法写入内容。
2.document.write(),document.writeln()
document.write方法用于向当前文档写入内容。
在网页的首次渲染阶段,只要页面没有关闭写入(即没有执行document.close()),document.write写入的内容就会追加在已有内容的后面。
如果页面已经解析完成(DOMContentLoaded事件发生之后),再调用write方法,它会先调用open方法,擦除当前文档所有内容,然后再写入。
如果在页面渲染过程中调用write方法,并不会自动调用open方法。(可以理解成,open方法已调用,但close方法还未调用。)
document.writeln方法与write方法完全一致,除了会在输出内容的尾部添加换行符
3.document.elementFromPoint(),document.elementsFromPoint()
document.elementFromPoint方法返回位于页面指定位置最上层的元素节点。
var element = document.elementFromPoint(50, 50);
上面代码选中在(50, 50)这个坐标位置的最上层的那个 HTML 元素。
document.elementsFromPoint()返回一个数组,成员是位于指定坐标(相对于视口)的所有元素。
4.document.caretRangeFromPoint()
document.caretRangeFromPoint方法返回位于页面指定位置最上层的Range对象。
5.document.createTextNode()
document.createTextNode方法用来生成文本节点(Text实例),并返回该节点。它的参数是文本节点的内容。
var newDiv = document.createElement('div');
var newContent = document.createTextNode('Hello');
newDiv.appendChild(newContent);
上面代码新建一个div节点和一个文本节点,然后将文本节点插入div节点。
这个方法可以确保返回的节点,被浏览器当作文本渲染,而不是当作 HTML 代码渲染。因此,可以用来展示用户的输入,避免 XSS 攻击。
6.document.createAttribute()
document.createAttribute方法生成一个新的属性节点(Attr实例),并返回它。
7.document.createAttribute()
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');
8.document.createComment()
document.createComment方法生成一个新的注释节点,并返回该节点。
var CommentNode = document.createComment(data);
document.createComment方法的参数是一个字符串,会成为注释节点的内容。
9.document.createDocumentFragment()
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>节点,这些子节点被一次性插入了当前文档。
10.document.createEvent()
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的事件实例,然后触发该事件。
11.document.addEventListener(),document.removeEventListener(),document.dispatchEvent()
这三个方法用于处理document节点的事件。它们都继承自EventTarget接口,详细介绍参见《EventTarget 接口》一章。
// 添加事件监听函数
document.addEventListener('click', listener, false);
// 移除事件监听函数
document.removeEventListener('click', listener, false);
// 触发事件
var event = new Event('click');
document.dispatchEvent(event);
12.document.hasFocus()
document.hasFocus方法返回一个布尔值,表示当前文档之中是否有元素被激活或获得焦点。
13.document.adoptNode(),document.importNode()
document.adoptNode方法将某个节点及其子节点,从原来所在的文档或DocumentFragment里面移除,归属当前document对象,返回插入后的新节点。(返回DocumentFragment里面移除的节点)
document.importNode方法则是从原来所在的文档或DocumentFragment里面,拷贝某个节点及其子节点,让它们归属当前document对象。
var node = document.importNode(externalNode, deep);
14.document.createNodeIterator()
document.createNodeIterator方法返回一个子节点遍历器。
var nodeIterator = document.createNodeIterator(
document.body,
NodeFilter.SHOW_ELEMENT
);
document.createNodeIterator方法第一个参数为所要遍历的根节点,第二个参数为所要遍历的节点类型,这里指定为元素节点(NodeFilter.SHOW_ELEMENT)。几种主要的节点类型写法如下。
- 所有节点:NodeFilter.SHOW_ALL
- 元素节点:NodeFilter.SHOW_ELEMENT
- 文本节点:NodeFilter.SHOW_TEXT
- 评论节点:NodeFilter.SHOW_COMMENT
document.createNodeIterator方法返回一个“遍历器”对象(NodeFilter实例)。该实例的nextNode()方法和previousNode()方法,可以用来遍历所有子节点。
15.document.createTreeWalker()
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);
}
16.document.execCommand(),document.queryCommandSupported(),document.queryCommandEnabled()
如果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()方法返回一个布尔值,表示当前是否可用某种样式改变。
17.document.getSelection()
这个方法指向window.getSelection(),参见window对象一节的介绍。
更多
document.querySelector(),document.querySelectorAll()
document.getElementsByTagName()
document.getElementsByClassName()
document.getElementsByName()
六.Element 节点
Element节点对象对应网页的 HTML 元素。每一个 HTML 元素,在 DOM 树上都会转化成一个Element节点对象(以下简称元素节点)。
Element对象继承了Node接口,因此Node的属性和方法在Element对象都存在。
1.实例属性
1.元素特性的相关属性
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
2.元素状态的相关属性
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 的列表转为字符串。
其他属性
- Element.innerHTML
- Element.outerHTML
- Element.clientHeight,Element.clientWidth
- Element.clientLeft,Element.clientTop
- Element.scrollHeight,Element.scrollWidth
- Element.scrollLeft,Element.scrollTop
- Element.offsetParent
- Element.offsetHeight,Element.offsetWidth
- Element.offsetLeft,Element.offsetTop
- Element.style
- Element.children,Element.childElementCount
- Element.firstElementChild,Element.lastElementChild
- Element.nextElementSibling,Element.previousElementSibling
2.实例方法
1.属性相关方法
getAttribute():读取某个属性的值getAttributeNames():返回当前元素的所有属性名setAttribute():写入属性值hasAttribute():某个属性是否存在hasAttributes():当前元素是否有属性removeAttribute():删除属性
2.Element.closest()
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操作一样
3.Element.matches()
Element.matches方法返回一个布尔值,表示当前元素是否匹配给定的 CSS 选择器。
el.matches('.someClass') //样式包含someClass 返回true
document.querySelector('input').matches('[accessKey]') //包含属性accessKey 返回true
4.Element.scrollIntoView()
Element.scrollIntoView方法滚动当前元素,进入浏览器的可见区域,类似于设置window.location.hash的效果。
el.scrollIntoView(); // 等同于el.scrollIntoView(true)
el.scrollIntoView(false);
5.Element.getBoundingClientRect()
面代码中,getBoundingClientRect方法返回的rect对象,具有以下属性(全部为只读)。
x:元素左上角相对于视口的横坐标y:元素左上角相对于视口的纵坐标height:元素高度width:元素宽度left:元素左上角相对于视口的横坐标,与x属性相等right:元素右边界相对于视口的横坐标(等于x + width)top:元素顶部相对于视口的纵坐标,与y属性相等bottom:元素底部相对于视口的纵坐标(等于y + height)
由于元素相对于视口(viewport)的位置,会随着页面滚动变化,因此表示位置的四个属性值,都不是固定不变的。如果想得到绝对位置,可以将left属性加上window.scrollX,top属性加上window.scrollY。
6.Element.getClientRects()
上面代码是一个行内元素<span>,如果它在页面上占据三行,getClientRects方法返回的对象就有三个成员,如果它在页面上占据一行,getClientRects方法返回的对象就只有一个成员。
7.Element.insertAdjacentElement(),Element.insertAdjacentHTML(),Element.insertAdjacentText()
Element.insertAdjacentElement方法在相对于当前元素的指定位置,插入一个新的节点。该方法返回被插入的节点,如果插入失败,返回null。
element.insertAdjacentElement(position, element);
第一个参数只可以取如下的值。
beforebegin:当前元素之前afterbegin:当前元素内部的第一个子节点前面beforeend:当前元素内部的最后一个子节点后面afterend:当前元素之后
七.属性的操作
HTML 元素包括标签名和若干个键值对,这个键值对就称为“属性”(attribute)。
属性本身是一个对象(Attr对象),但是实际上,这个对象极少使用。一般都是通过元素节点对象(HTMlElement对象)来操作属性。本章介绍如何操作这些属性。
元素节点提供六个方法,用来操作属性。
getAttribute()getAttributeNames()setAttribute()hasAttribute()hasAttributes()removeAttribute()
dataset 属性
有时,需要在HTML元素上附加数据,供 JavaScript 脚本使用。更好的解决方法是,使用标准提供的data-*属性。可以添加复杂的数据。
八.Text 节点的概念
文本节点(Text)代表元素节点(Element)和属性节点(Attribute)的文本内容。如果一个节点只包含一段文本,那么它就有一个文本子节点,代表该节点的文本内容。
通常我们使用父节点的firstChild、nextSibling等属性获取文本节点,或者使用Document节点的createTextNode方法创造一个文本节点。
1.Text 节点的属性
data属性等同于nodeValue属性,用来设置或读取文本节点的内容。
2.Text 节点的方法
appendData(),deleteData(),insertData(),replaceData(),subStringData()
九.CSS 操作
1.HTML 元素的 style 属性
div.setAttribute(
'style',
'background-color:red;' + 'border:1px solid black;'
);
2.CSSStyleDeclaration实例
1.CSSStyleDeclaration 接口
CSSStyleDeclaration 接口用来操作元素的样式。三个地方部署了这个接口。
- 元素节点的
style属性(Element.style) CSSStyle实例的style属性window.getComputedStyle()的返回值
个对象所包含的属性与 CSS 规则一一对应,但是名字需要改写,比如background-color写成backgroundColor。改写的规则是将横杠从 CSS 属性名中去除,然后将横杠后的第一个字母大写。如果 CSS 属性名是 JavaScript 保留字,则规则名之前需要加上字符串css,比如float写成cssFloat。
注意,该对象的属性值都是字符串,设置时必须包括单位,但是不含规则结尾的分号。比如,divStyle.width不能写为100,而要写为100px。
2.CSSStyleDeclaration 实例属性
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
3.CSSStyleDeclaration 实例方法
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。
4.侦测属性
这种侦测方法可以写成一个函数。
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
3.CSS 对象
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元素真正的背景色。
4.StyleSheet 接口
StyleSheet接口代表网页的一张样式表,包括<link>元素加载的样式表和<style>元素内嵌的样式表。
获取StyleSheet实例
var sheets = document.styleSheets;
var sheet = document.styleSheets[0];
sheet instanceof StyleSheet // true
5.CSSRuleList 接口
StyleSheet实例的cssRules属性指向的就是CSSRuleList实例
6.CSSRule 接口
CSSRule实例组成CSSRuleList实例
7.CSSStyleRule 接口
如果一条 CSS 规则是普通的样式规则(不含特殊的 CSS 命令),那么除了 CSSRule 接口,它还部署了 CSSStyleRule 接口。
8.CSSMediaRule 接口
如果一条 CSS 规则是@media代码块,那么它除了 CSSRule 接口,还部署了 CSSMediaRule 接口。
具体参考文档:wangdoc.com/javascript/…
十.Mutation Observer API
Mutation Observer API 用来监视 DOM 变动。DOM 的任何变动,比如节点的增减、属性的变动、文本内容的变动,这个 API 都可以得到通知。
概念上,它很接近事件,可以理解为 DOM 发生变动就会触发 Mutation Observer 事件。但是,它与事件有一个本质不同:事件是同步触发,也就是说,DOM 的变动立刻会触发相应的事件;Mutation Observer 则是异步触发,DOM 的变动并不会马上触发,而是要等到当前所有 DOM 操作都结束才触发。
Mutation Observer 有以下特点。
- 它等待所有脚本任务完成后,才会运行(即异步触发方式)。
- 它把 DOM 变动记录封装成一个数组进行处理,而不是一条条个别处理 DOM 变动。
- 它既可以观察 DOM 的所有类型变动,也可以指定只观察某一类变动。