1 什麼是DOM
文件物件模型 (DOM) 是HTML和XML文件的程式設計介面。它提供了對文件的結構化的表述,並定義了一種方式可以使從程式中對該結構進行訪問,從而改變文件的結構,樣式和內容。
文件物件模型 (DOM) 是對HTML檔案的另一種展示,通俗地說,一個HTML 檔案,我們可以用編輯器以程式碼的形式展示它,也可以用瀏覽器以頁面的形式展示它,同一份檔案通過不同的展示方式,就有了不一樣的表現形式。而DOM 將文件解析為一個由節點和物件(包含屬性和方法的物件)組成的結構集合。簡言之,它會將web頁面和指令碼或程式語言連線起來,我們可以使用指令碼或者程式語言通過DOM 來改變或者控制web頁面。
2 如何訪問DOM
我們可以通過JavaScript 來呼叫document
和window
元素的API來操作文件或者獲取文件的資訊。
3 Node
Node 是一個介面,有許多介面都從Node 繼承方法和屬性:
Document
, Element
, CharacterData (which Text, Comment, and CDATASection inherit)
, ProcessingInstruction
, DocumentFragment
, DocumentType
, Notation
, Entity
, EntityReference
。
Node 有一個nodeType
的屬性表示Node 的型別,是一個整數,不同的值代表不同的節點型別。具體如下表所示:
節點型別常量
常量 | 值 | 描述 |
---|---|---|
Node.ELEMENT_NODE |
1 | 一個元素節點,例如 <p> 和 <div> |
Node.TEXT_NODE |
3 | Element 或者 Attr 中實際的文字 |
Node.PROCESSING_INSTRUCTION_NODE |
7 | 一個用於XML文件的 ProcessingInstruction ,例如 <?xml-stylesheet ... ?> 宣告 |
Node.COMMENT_NODE |
8 | 一個 Comment 節點 |
Node.DOCUMENT_NODE |
9 | 一個 Document 節點 |
Node.DOCUMENT_TYPE_NODE |
10 | 描述文件型別的 DocumentType 節點。例如 <!DOCTYPE html> 就是用於 HTML5 的 |
Node.DOCUMENT_FRAGMENT_NODE |
11 | 一個 DocumentFragment 節點 |
已棄用的節點型別常量
常量 | 值 | 描述 |
---|---|---|
Node.ATTRIBUTE_NODE |
2 | 元素的耦合屬性。在DOM4 規範裡Node 介面將不再實現這個元素屬性 |
Node.CDATA_SECTION_NODE |
4 | 一個CDATASection 。在DOM4 規範裡被移除 |
Node.ENTITY_REFERENCE_NODE |
5 | 一個XML 實體引用節點。在DOM4 規範裡被移除 |
Node.ENTITY_NODE |
6 | 一個XML <!ENTITY ...> 節點。在DOM4 規範中被移除 |
Node.NOTATION_NODE |
12 | 一個XML <!NOTATION ...> 節點。在DOM4 規範裡被移除 |
假設我們要判斷一個Node 是不是一個元素
,通過查表可知元素
的nodeType
屬性值為1,程式碼可以這麼寫:
if(X.nodeType === 1){
console.log('X 是一個元素');
}
複製程式碼
在Node 型別中,比較常用的就是element
,text
,comment
,document
,document_fragment
這幾種型別。
3.1 Element
Element提供了對元素標籤名,子節點和特性的訪問,我們常用HTML元素比如div
,span
,a
等標籤就是element
中的一種。Element有下面幾條特性:
(1)nodeType為1
(2)nodeName為元素標籤名,tagName也是返回標籤名
(3)nodeValue為null
(4)parentNode可能是Document或Element
(5)子節點可能是Element,Text,Comment,Processing_Instruction,CDATASection或EntityReference
3.2 Text
Text表示文字節點,它包含的是純文字內容,不能包含html程式碼,但可以包含轉義後的html程式碼。Text有下面的特性:
(1)nodeType為3
(2)nodeName為#text
(3)nodeValue為文字內容
(4)parentNode是一個Element
(5)沒有子節點
3.3 Comment
Comment表示HTML文件中的註釋,它有下面的幾種特徵:
(1)nodeType為8
(2)nodeName為#comment
(3)nodeValue為註釋的內容
(4)parentNode可能是Document或Element
(5)沒有子節點
3.4 Document
Document表示文件,在瀏覽器中,document
物件是HTMLDocument的一個例項,表示整個頁面,它同時也是window物件的一個屬性。Document有下面的特性:
(1)nodeType為9
(2)nodeName為#document
(3)nodeValue為null
(4)parentNode為null
(5)子節點可能是一個DocumentType或Element
3.5 DocumentFragment
DocumentFragment是所有節點中唯一一個沒有對應標記的型別,它表示一種輕量級的文件,可能當作一個臨時的倉庫用來儲存可能會新增到文件中的節點。DocumentFragment有下面的特性:
(1)nodeType為11
(2)nodeName為#document-fragment
(3)nodeValue為null
(4)parentNode為null
4 節點建立型API
用如其名,這類API是用來建立節點的
4.1 createElement
createElement
通過傳入指定的一個標籤名來建立一個元素,如果傳入的標籤名是一個未知的,則會建立一個自定義的標籤,注意:IE8以下瀏覽器不支援自定義標籤。
語法
let element = document.createElement(tagName);
複製程式碼
使用createElement
要注意:通過createElement
建立的元素並不屬於HTML文件,它只是建立出來,並未新增到HTML文件中,要呼叫appendChild
或insertBefore
等方法將其新增到HTML文件樹中。
例子:
let elem = document.createElement("div");
elem.id = 'test';
elem.style = 'color: red';
elem.innerHTML = '我是新建立的節點';
document.body.appendChild(elem);
複製程式碼
執行結果為:
4.2 createTextNode
createTextNode
用來建立一個文字節點
語法
var text = document.createTextNode(data);
複製程式碼
createTextNode
接收一個引數,這個引數就是文字節點中的文字,和createElement
一樣,建立後的文字節點也只是獨立的一個節點,同樣需要appendChild
將其新增到HTML文件樹中
例子:
var node = document.createTextNode("我是文字節點");
document.body.appendChild(node);
複製程式碼
執行結果為:
4.3 cloneNode
cloneNode
返回撥用該方法的節點的一個副本
語法
var dupNode = node.cloneNode(deep);
複製程式碼
node
將要被克隆的節點
dupNode
克隆生成的副本節點
deep
(可選)是否採用深度克隆,如果為true,則該節點的所有後代節點也都會被克隆,如果為false,則只克隆該節點本身.
這裡有幾點要注意:
(1)和createElement
一樣,cloneNode
建立的節點只是遊離有HTML文件外的節點,要呼叫appendChild
方法才能新增到文件樹中
(2)如果複製的元素有id
,則其副本同樣會包含該id
,由於id
具有唯一性,所以在複製節點後必須要修改其id
(3)呼叫接收的deep
引數最好傳入,如果不傳入該引數,不同瀏覽器對其預設值的處理可能不同
注意
如果被複制的節點繫結了事件,則副本也會跟著繫結該事件嗎?這裡要分情況討論:
(1)如果是通過addEventListener或者比如onclick進行繫結事件,則副本節點不會繫結該事件
(2)如果是內聯方式繫結比如:<div onclick="showParent()"></div>
,這樣的話,副本節點同樣會觸發事件。
例子:
<body>
<div id="parent">
我是父元素的文字
<br/>
<span>
我是子元素
</span>
</div>
<button id="btnCopy">複製</button>
</body>
<script>
var parent = document.getElementById("parent");
document.getElementById("btnCopy").onclick = function(){
var parent2 = parent.cloneNode(true);
parent2.id = "parent2";
document.body.appendChild(parent2);
}
</script>
複製程式碼
執行結果為:
4.4 createDocumentFragment
DocumentFragments
是DOM節點。它們不是主DOM樹的一部分。通常的用例是建立文件片段,將元素附加到文件片段,然後將文件片段附加到DOM樹。在DOM樹中,文件片段被其所有的子元素所代替。
因為文件片段存在於記憶體中,並不在DOM樹中,所以將子元素插入到文件片段時不會引起頁面迴流(reflow)(對元素位置和幾何上的計算)。因此,使用文件片段document fragments
通常會起到優化效能的作用。
語法
let fragment = document.createDocumentFragment();
複製程式碼
例子:
<body>
<ul id="ul"></ul>
</body>
<script>
(function()
{
var start = Date.now();
var str = '', li;
var ul = document.getElementById('ul');
var fragment = document.createDocumentFragment();
for(var i=0; i<1000; i++)
{
li = document.createElement('li');
li.textContent = '第'+(i+1)+'個子節點';
fragment.appendChild(li);
}
ul.appendChild(fragment);
})();
</script>
複製程式碼
執行結果為:
4.5 節點建立型API總結
節點建立型API主要包括createElement
,createTextNode
,cloneNode
和createDocumentFragment
四個方法,需要注意下面幾點:
(1)它們建立的節點只是一個孤立的節點,要通過appendChild
新增到文件中
(2)cloneNode
要注意如果被複制的節點是否包含子節點以及事件繫結等問題
(3)使用createDocumentFragment
來解決新增大量節點時的效能問題
5 頁面修改型API
前面我們提到節點建立型API,它們只是建立節點,並沒有真正修改到頁面內容,而是要呼叫·appendChild·來將其新增到文件樹中。我在這裡將這類會修改到頁面內容歸為一類。
修改頁面內容的api主要包括:appendChild
,insertBefore
,removeChild
,replaceChild
。
5.1 appendChild
appendChild
我們在前面已經用到多次,就是將指定的節點新增到呼叫該方法的節點的子元素的末尾。
語法
parent.appendChild(child);
複製程式碼
child節點將會作為parent節點的最後一個子節點。
appendChild
這個方法很簡單,但是還有有一點需要注意:如果被新增的節點是一個頁面中存在的節點,則執行後這個節點將會新增到指定位置,其原本所在的位置將移除該節點,也就是說不會同時存在兩個該節點在頁面上,相當於把這個節點移動到另一個地方。
如果child繫結了事件,被移動時,它依然繫結著該事件。
例子:
<body>
<div id="child">
要被新增的節點
</div>
<br/>
<br/>
<br/>
<div id="parent">
要移動的位置
</div>
<input id="btnMove" type="button" value="移動節點" />
</body>
<script>
document.getElementById("btnMove").onclick = function(){
var child = document.getElementById("child");
document.getElementById("parent").appendChild(child);
}
</script>
複製程式碼
執行結果:
5.2 insertBefore
insertBefore
用來新增一個節點到一個參照節點之前
語法
parentNode.insertBefore(newNode,refNode);
複製程式碼
parentNode
表示新節點被新增後的父節點
newNode
表示要新增的節點
refNode
表示參照節點,新節點會新增到這個節點之前
例子:
<body>
<div id="parent">
父節點
<div id="child">
子元素
</div>
</div>
<input type="button" id="insertNode" value="插入節點" />
</body>
<script>
var parent = document.getElementById("parent");
var child = document.getElementById("child");
document.getElementById("insertNode").onclick = function(){
var newNode = document.createElement("div");
newNode.textContent = "新節點"
parent.insertBefore(newNode,child);
}
</script>
複製程式碼
執行結果:
關於第二個引數參照節點還有幾個注意的地方:
(1)refNode是必傳的,如果不傳該引數會報錯
(2)如果refNode是undefined或null,則insertBefore會將節點新增到子元素的末尾
5.3 removeChild
刪除指定的子節點並返回
語法
var deletedChild = parent.removeChild(node);
複製程式碼
deletedChild
指向被刪除節點的引用,它等於node
,被刪除的節點仍然存在於記憶體中,可以對其進行下一步操作。
注意:如果被刪除的節點不是其子節點,則程式將會報錯。我們可以通過下面的方式來確保可以刪除:
if(node.parentNode){
node.parentNode.removeChild(node);
}
複製程式碼
執行結果:
5.4 replaceChild
replaceChild
用於使用一個節點替換另一個節點
語法
parent.replaceChild(newChild,oldChild);
複製程式碼
newChild
是替換的節點,可以是新的節點,也可以是頁面上的節點,如果是頁面上的節點,則其將被轉移到新的位置
oldChild
是被替換的節點
例子:
<body>
<div id="parent">
父節點
<div id="child">
子元素
</div>
</div>
<input type="button" id="insertNode" value="替換節點" />
</body>
<script>
var parent = document.getElementById("parent");
var child = document.getElementById("child");
document.getElementById("insertNode").onclick = function(){
var newNode = document.createElement("div");
newNode.textContent = "新節點"
parent.replaceChild(newNode,child)
}
複製程式碼
執行結果:
5.5 頁面修改型API總結
頁面修改型API主要是這四個介面,要注意幾個特點:
(1)不管是新增還是替換節點,如果新增或替換的節點是原本存在頁面上的,則其原來位置的節點將被移除,也就是說同一個節點不能存在於頁面的多個位置
(2)節點本身繫結的事件會不會消失,會一直保留著。
6 節點查詢型API
6.1 document.getElementById
這個介面很簡單,根據元素id返回元素,返回值是Element型別,如果不存在該元素,則返回null
語法
var element = document.getElementById(id);
複製程式碼
使用這個介面有幾點要注意:
(1)元素的Id是大小寫敏感的,一定要寫對元素的id
(2)HTML文件中可能存在多個id相同的元素,則返回第一個元素
(3)只從文件中進行搜尋元素,如果建立了一個元素並指定id,但並沒有新增到文件中,則這個元素是不會被查詢到的
例子:
<body>
<p id="para1">Some text here</p>
<button onclick="changeColor('blue');">blue</button>
<button onclick="changeColor('red');">red</button>
</body>
<script>
function changeColor(newColor) {
var elem = document.getElementById("para1");
elem.style.color = newColor;
}
</script>
複製程式碼
執行結果:
6.2 document.getElementsByTagName
返回一個包括所有給定標籤名稱的元素的HTML集合HTMLCollection。 整個檔案結構都會被搜尋,包括根節點。返回的 HTML集合是動態的, 意味著它可以自動更新自己來保持和 DOM 樹的同步而不用再次呼叫document.getElementsByTagName()
語法
var elements = document.getElementsByTagName(name);
複製程式碼
(1)如果要對HTMLCollection集合進行迴圈操作,最好將其長度快取起來,因為每次迴圈都會去計算長度,暫時快取起來可以提高效率
(2)如果沒有存在指定的標籤,該介面返回的不是null,而是一個空的HTMLCollection
(3)name
是一個代表元素的名稱的字串。特殊字元 "*" 代表了所有元素。
例子:
<body>
<div>div1</div>
<div>div2</div>
<input type="button" value="顯示數量" id="btnShowCount"/>
<input type="button" value="新增div" id="btnAddDiv"/>
</body>
<script>
var divList = document.getElementsByTagName("div");
document.getElementById("btnAddDiv").onclick = function(){
var div = document.createElement("div");
div.textContent ="div" + (divList.length+1);
document.body.appendChild(div);
}
document.getElementById("btnShowCount").onclick = function(){
alert(divList.length);
}
</script>
複製程式碼
這段程式碼中有兩個按鈕,一個按鈕是顯示HTMLCollection元素的個數,另一個按鈕可以新增一個div標籤到文件中。前面提到HTMLCollcetion元素是即時的表示該集合是隨時變化的,也就是是文件中有幾個div,它會隨時進行變化,當我們新增一個div後,再訪問HTMLCollection時,就會包含這個新增的div。
執行結果:
6.3 document.getElementsByName
getElementsByName
主要是通過指定的name
屬性來獲取元素,它返回一個即時的NodeList物件
語法
var elements = document.getElementsByName(name)
複製程式碼
使用這個介面主要要注意幾點:
(1)返回物件是一個即時的NodeList,它是隨時變化的
(2)在HTML元素中,並不是所有元素都有name
屬性,比如div
是沒有name
屬性的,但是如果強制設定div
的name
屬性,它也是可以被查詢到的
(3)在IE中,如果id
設定成某個值,然後傳入getElementsByName
的引數值和id值一樣,則這個元素是會被找到的,所以最好不好設定同樣的值給id
和name
例子:
<script type="text/javascript">
function getElements()
{
var x=document.getElementsByName("myInput");
alert(x.length);
}
</script>
<body>
<input name="myInput" type="text" size="20" /><br />
<input name="myInput" type="text" size="20" /><br />
<input name="myInput" type="text" size="20" /><br />
<br />
<input type="button" onclick="getElements()" value="How many elements named 'myInput'?" />
</body>
複製程式碼
執行結果:
6.4 document.getElementsByClassName
這個API是根據元素的class返回一個即時的HTMLCollection
語法
var elements = document.getElementsByClassName(names); // or:
var elements = rootElement.getElementsByClassName(names);
複製程式碼
elements
是一個實時集合,包含了找到的所有元素names
是一個字串,表示要匹配的類名列表;類名通過空格分隔getElementsByClassName
可以在任何元素上呼叫,不僅僅是document
。呼叫這個方法的元素將作為本次查詢的根元素
這個介面有下面幾點要注意:
(1)返回結果是一個即時的HTMLCollection,會隨時根據文件結構變化
(2)IE9以下瀏覽器不支援
(3)如果要獲取2個以上classname
,可傳入多個classname
,每個用空格相隔,例如
var elements = document.getElementsByClassName("test1 test2");
複製程式碼
例子:
- 獲取所有
class
為 'test' 的元素
var elements = document.getElementsByClassName('test');
複製程式碼
- 獲取所有
class
同時包括 'red' 和 'test' 的元素
var elements = document.getElementsByClassName('red test');
複製程式碼
- 在
id
為'main'的元素的子節點中,獲取所有class
為'test'的元素
var elements = document.getElementById('main').getElementsByClassName('test');
複製程式碼
- 我們還可以對任意的HTMLCollection 使用
Array.prototype
的方法,呼叫時傳遞HTMLCollection 作為方法的引數。這裡我們將查詢到所有class
為'test'的div
元素:
var testElements = document.getElementsByClassName('test');
var testDivs = Array.prototype.filter.call(testElements, function(testElement){
return testElement.nodeName === 'DIV';;
});
複製程式碼
6.5 document.querySelector和document.querySelectorAll
這兩個API很相似,通過css選擇器來查詢元素,注意選擇器要符合CSS選擇器的規則
- 6.5.1 document.querySelector
document.querySelector
返回第一個匹配的元素,如果沒有匹配的元素,則返回null
語法
var element = document.querySelector(selectors);
複製程式碼
注意,由於返回的是第一個匹配的元素,這個api使用的深度優先搜尋來獲取元素。
例子:
<body>
<div>
<div>
<span class="test">第三級的span</span>
</div>
</div>
<div class="test">
同級的第二個div
</div>
<input type="button" id="btnGet" value="獲取test元素" />
</body>
<script>
document.getElementById("btnGet").addEventListener("click",function(){
var element = document.querySelector(".test");
alert(element.textContent);
})
</script>
複製程式碼
兩個class
都包含“test”的元素,一個在文件樹的前面,但是它在第三級,另一個在文件樹的後面,但它在第一級,通過querySelector
獲取元素時,它通過深度優先搜尋,拿到文件樹前面的第三級的元素。
執行結果:
- 6.5.2 document.querySelectorAll 返回的是所有匹配的元素,而且可以匹配多個選擇符
語法
var elementList = document.querySelectorAll(selectors);
複製程式碼
elementList
是一個靜態的NodeList
型別的物件selectors
是一個由逗號連線的包含一個或多個CSS選擇器的字串- 如果
selectors
引數中包含CSS偽元素,則返回一個空的elementList
例子:
var matches = document.querySelectorAll("div.note, div.alert");
複製程式碼
返回一個文件中所有的class
為"note"
或者"alert"
的div
元素
<body>
<div class="test">
class為test
</div>
<div id="test">
id為test
</div>
<input id="btnShow" type="button" value="顯示內容" />
</body>
<script>
document.getElementById("btnShow").addEventListener("click",function(){
var elements = document.querySelectorAll("#test,.test");
for(var i = 0,length = elements.length;i<length;i++){
alert(elements[i].textContent);
}
})
</script>
複製程式碼
這段程式碼通過querySelectorAll
,使用id選擇器和class選擇器選擇了兩個元素,並依次輸出其內容。要注意兩點:
(1)querySelectorAll也是通過深度優先搜尋,搜尋的元素順序和選擇器的順序無關
(2)返回的是一個非即時的NodeList,也就是說結果不會隨著文件樹的變化而變化
相容性問題:querySelector
和querySelectorAll
在ie8以下的瀏覽器不支援。
執行結果:
7 節點關係型API
在html文件中的每個節點之間的關係都可以看成是家譜關係,包含父子關係,兄弟關係等等
7.1 父關係型API
7.1.1 parentNode
每個節點都有一個parentNode屬性,它表示元素的父節點。Element的父節點可能是Element,Document或DocumentFragment
7.1.2 parentElement
返回元素的父元素節點,與parentNode的區別在於,其父節點必須是一個Element,如果不是,則返回null
7.2 子關係型APPI
7.2.1 childNodes
返回一個即時的NodeList,表示元素的子節點列表,子節點可能會包含文字節點,註釋節點等
7.2.2 children:
一個即時的HTMLCollection,子節點都是Element,IE9以下瀏覽器不支援
children
屬性為只讀屬性,物件型別為HTMLCollection,你可以使用elementNodeReference.children[1].nodeName
來獲取某個子元素的標籤名稱
7.2.3 firstChild
只讀屬性返回樹中節點的第一個子節點,如果節點是無子節點,則返回 null
7.2.4 lastChild
返回當前節點的最後一個子節點。如果父節點為一個元素節點,則子節點通常為一個元素節點,或一個文字節點,或一個註釋節點。如果沒有子節點,則返回null
7.2.5 hasChildNodes
返回一個布林值,表明當前節點是否包含有子節點.
7.3 兄弟關係型API
7.3.1 previousSibling
返回當前節點的前一個兄弟節點,沒有則返回null
Gecko核心的瀏覽器會在原始碼中標籤內部有空白符的地方插入一個文字結點到文件中.因此,使用諸如Node.firstChild
和Node.previousSibling
之類的方法可能會引用到一個空白符文字節點, 而不是使用者所預期得到的節點
7.3.2 previousElementSibling
previousElementSibling
返回當前元素在其父元素的子元素節點中的前一個元素節點,如果該元素已經是第一個元素節點,則返回null
,該屬性是隻讀的。注意IE9以下瀏覽器不支援
7.3.3 nextSibling
Node.nextSibling
是一個只讀屬性,返回其父節點的childNodes
列表中緊跟在其後面的節點,如果指定的節點為最後一個節點,則返回null
Gecko核心的瀏覽器會在原始碼中標籤內部有空白符的地方插入一個文字結點到文件中.因此,使用諸如Node.firstChild
和Node.previousSibling
之類的方法可能會引用到一個空白符文字節點, 而不是使用者所預期得到的節點
7.3.4 nextElementSibling
nextElementSibling
返回當前元素在其父元素的子元素節點中的後一個元素節點,如果該元素已經是最後一個元素節點,則返回null
,該屬性是隻讀的。注意IE9以下瀏覽器不支援
8 元素屬性型API
8.1 setAttribute
設定指定元素上的一個屬性值。如果屬性已經存在,則更新該值; 否則將新增一個新的屬性用指定的名稱和值
語法
element.setAttribute(name, value);
複製程式碼
其中name
是特性名,value
是特性值。如果元素不包含該特性,則會建立該特性並賦值。
例子:
<body>
<div id="div1">ABC</div>
</body>
<script>
let div1 = document.getElementById("div1");
div1.setAttribute("align", "center");
</script>
複製程式碼
執行結果:
如果元素本身包含指定的特性名為屬性,則可以世界訪問屬性進行賦值,比如下面兩條程式碼是等價的:
element.setAttribute("id","test");
element.id = "test";
複製程式碼
8.2 getAttribute
getAttribute()
返回元素上一個指定的屬性值。如果指定的屬性不存在,則返回null
或""
(空字串)
語法
let attribute = element.getAttribute(attributeName);
複製程式碼
attribute
是一個包含attributeName
屬性值的字串。attributeName
是你想要獲取的屬性值的屬性名稱
例子:
<body>
<div id="div1">ABC</div>
</body>
<script>
let div1 = document.getElementById("div1");
let align = div1.getAttribute("align");
alert(align);
</script>
複製程式碼
執行結果:
8.3 removeAttribute
removeAttribute()
從指定的元素中刪除一個屬性
語法
element.removeAttribute(attrName)
複製程式碼
attrName
是一個字串,將要從元素中刪除的屬性名
例子:
<body>
<div id="div1" style="color:red" width="200px">ABC
</div>
</body>
<script>
let div = document.getElementById("div1")
div.removeAttribute("style");
</script>
複製程式碼
在執行之前div
有個style="color:red"
的屬性,在執行之後這個屬性就被刪除了
執行結果:
9 元素樣式型API
9.1 window.getComputedStyle
Window.getComputedStyle()
方法給出應用活動樣式表後的元素的所有CSS屬性的值,並解析這些值可能包含的任何基本計算
假設某個元素並未設定高度而是通過其內容將其高度撐開,這時候要獲取它的高度就要用到getComputedStyle
語法
var style = window.getComputedStyle(element[, pseudoElt]);
複製程式碼
element
是要獲取的元素,pseudoElt
指定一個偽元素進行匹配。
返回的style
是一個CSSStyleDeclaration物件。
通過style
可以訪問到元素計算後的樣式
9.2 getBoundingClientRect
getBoundingClientRect
用來返回元素的大小以及相對於瀏覽器可視視窗的位置
語法
var clientRect = element.getBoundingClientRect();
複製程式碼
clientRect
是一個DOMRect物件,包含left,top,right,bottom,它是相對於可視視窗的距離,滾動位置發生改變時,它們的值是會發生變化的。除了IE9以下瀏覽器,還包含元素的height和width等資料
9.3 直接修改元素的樣式
例子:
elem.style.color = 'red';
elem.style.setProperty('font-size', '16px');
elem.style.removeProperty('color');
複製程式碼
9.4 動態新增樣式規則
例子:
var style = document.createElement('style');
style.innerHTML = 'body{color:red} #top:hover{background-color: red;color: white;}';
document.head.appendChild(style););
複製程式碼
10 總結
JavaScript中的API太多了,將這些API記住並熟練使用對JavaScript的學習是有很大的幫助