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 有如下特色。