js文档笔记5——DOM

一.概述

1.DOM

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

2.节点

DOM 的最小组成单位叫作节点(node)。文档的树形结构(DOM 树),就是由各类不一样类型的节点组成。每一个节点能够看做是文档树的一片叶子。java

节点的类型有七种。node

  • Document:整个文档树的顶层节点
  • DocumentTypedoctype标签(好比<!DOCTYPE html>
  • Element:网页的各类HTML标签(好比<body><a>等)
  • Attribute:网页元素的属性(好比class="right"
  • Text:标签之间或标签包含的文本
  • Comment:注释
  • DocumentFragment:文档的片断

浏览器提供一个原生的节点对象Node,上面这七种节点都继承了Node,所以具备一些共同的属性和方法。jquery

3.节点树

一个文档的全部节点,按照所在的层级,能够抽象成一种树状结构。这种树状结构就是 DOM 树。数组

二.Node 接口

1.属性

1.Node.prototype.nodeType

1.nodeType属性返回一个整数值,表示节点的类型。浏览器

不一样节点的nodeType属性值和对应的常量以下。bash

  • 文档节点(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属性返回节点的名称。cookie

// 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内部的一个子节点referenceNodenewNode将插在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 提供两种节点集合,用于容纳多个节点:NodeListHTMLCollection

1.NodeList

NodeList实例是一个相似数组的对象,它的成员是节点对象。经过如下方法能够获得NodeList实例。

  • Node.childNodes
  • document.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.linksdocument.formsdocument.images等。

若是元素节点有idname属性,那么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有对子节点操做的方法

  1. 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对象有不一样的办法能够获取。

  • 正常的网页,直接使用documentwindow.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.locationdocument.location属性,能够拿到这个对象。

document.lastModified

document.lastModified属性返回一个字符串,表示当前文档最后修改的时间。不一样浏览器的返回值,日期格式是不同的。

document.title

document.title属性返回当前文档的标题。

document.characterSet

document.characterSet属性返回当前文档的编码,好比UTF-8ISO-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:加载完成

这个属性变化的过程以下。

  1. 浏览器开始解析 HTML 文档,document.readyState属性等于loading
  2. 浏览器遇到 HTML 文档中的<script>元素,而且没有asyncdefer属性,就暂停解析,开始执行脚本,这时document.readyState属性仍是等于loading
  3. HTML 文档解析完成,document.readyState属性变成interactive
  4. 浏览器等待图片、样式表、字体文件等外部资源加载完成,一旦所有加载完成,document.readyState属性变成complete

5.document.cookie

document.cookie属性用来操做浏览器 Cookie

6.document.designMode

document.designMode属性控制当前文档是否可编辑。该属性只有两个值onoff,默认值为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方法的参数是事件类型,好比UIEventsMouseEventsMutationEventsHTMLEvents

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 的列表转为字符串。

其余属性

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.scrollXtop属性加上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)的文本内容。若是一个节点只包含一段文本,那么它就有一个文本子节点,表明该节点的文本内容。

一般咱们使用父节点的firstChildnextSibling等属性获取文本节点,或者使用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 的全部类型变更,也能够指定只观察某一类变更。
相关文章
相关标签/搜索