DOM 自身存在不少類型,在DOM 基礎課程中大部分都有所接觸,好比Element 類型:
表示的是元素節點,再好比Text 類型:表示的是文本節點。DOM 也提供了一些擴展功能。html
一.DOM類型
DOM 基礎課程中,咱們瞭解了DOM 的節點而且瞭解怎樣查詢和操做節點,而自己這
些不一樣的節點,又有着不一樣的類型。node
1.Node 類型
Node 接口是DOM1 級就定義了,Node 接口定義了12 個數值常量以表示每一個節點的類
型值。除了IE 以外,全部瀏覽器均可以訪問這個類型。瀏覽器
雖然這裏介紹了12 種節點對象的屬性,用的多的其實也就幾個而已。服務器
- alert(Node.ELEMENT_NODE); //1,元素節點類型值
- alert(Node.TEXT_NODE); //2,文本節點類型值
咱們建議使用Node 類型的屬性來代替1,2 這些阿拉伯數字,有可能你們會以爲這樣豈
不是很繁瑣嗎?而且還有一個問題就是IE 不支持Node 類型。
若是隻有兩個屬性的話,用1,2 來代替會特別方便,但若是屬性特別多的狀況下,一、
二、三、四、五、六、七、八、九、十、十一、12,你根本就分不清哪一個數字表明的是哪一個節點。固然,
若是你只用1,2 兩個節點,那就另當別論了。
IE 不支持,咱們能夠模擬一個類,讓IE 也支持。app
- if (typeof Node == 'undefined') { //IE 返回
- window.Node = {
- ELEMENT_NODE : 1,
- TEXT_NODE : 3
- };
- }
2.Document 類型
Document 類型表示文檔,或文檔的根節點,而這個節點是隱藏的,沒有具體的元素標
籤。dom
- document; //document
- document.nodeType; //9,類型值
- document.childNodes[0]; //DocumentType,第一個子節點對象
- document.childNodes[0].nodeType; //非IE 爲10,IE 爲8
- document.childNodes[1]; //HTMLHtmlElement
- document.childNodes[1].nodeName; //HTML
若是想直接獲得<html>標籤的元素節點對象HTMLHtmlElement,沒必要使用childNodes
屬性這麼麻煩,可使用documentElement 便可。ide
- document.documentElement; //HTMLHtmlElement
在不少狀況下,咱們並不須要獲得<html>標籤的元素節點,而須要獲得更經常使用的<body>
標籤,以前咱們採用的是:document.getElementsByTagName('body')[0],那麼這裏提供一個
更加簡便的方法:document.body。函數
- document.body; //HTMLBodyElement
在<html>以前還有一個文檔聲明:<!DOCTYPE>會做爲某些瀏覽器的第一個節點來處
理,這裏提供了一個簡便方法來處理:document.doctype。性能
- document.doctype; //DocumentType
PS:IE8 中,若是使用子節點訪問,IE8 以前會解釋爲註釋類型Comment 節點,而
document.doctype 則會返回null。學習
- document.childNodes[0].nodeName //IE 會是#Comment
在Document 中有一些遺留的屬性和對象合集,能夠快速的幫助咱們精確的處理一些任
務。
- //屬性
- document.title; //獲取和設置<title>標籤的值
- document.URL; //獲取URL 路徑
- document.domain; //獲取域名,服務器端
- document.referrer; //獲取上一個URL,服務器端
- //對象集合
- document.anchors; //獲取文檔中帶name 屬性的<a>元素集合
- document.links; //獲取文檔中帶href 屬性的<a>元素集合
- document.applets; //獲取文檔中<applet>元素集合,已不用
- document.forms; //獲取文檔中<form>元素集合
- document.p_w_picpaths; //獲取文檔中<img>元素集合
3.Element 類型
Element 類型用於表現HTML 中的元素節點。在DOM 基礎那章,咱們已經能夠對元素
節點進行查找、建立等操做,元素節點的nodeType 爲1,nodeName 爲元素的標籤名。
元素節點對象在非IE 瀏覽器能夠返回它具體元素節點的對象類型。
PS:以上給出了部分對應,更多的元素對應類型,直接訪問調用便可。
4.Text 類型
Text 類型用於表現文本節點類型,文本不包含HTML,或包含轉義後的HTML。文本
節點的nodeType 爲3。
在同時建立兩個同一級別的文本節點的時候,會產生分離的兩個節點。
- var box = document.createElement('div');
- var text = document.createTextNode('Mr.');
- var text2 = document.createTextNode(Lee!);
- box.appendChild(text);
- box.appendChild(text2);
- document.body.appendChild(box);
- alert(box.childNodes.length); //2,兩個文本節點
PS:把兩個同鄰的文本節點合併在一塊兒使用normalize()便可。
- box.normalize(); //合併成一個節點
PS:有合併就有分離,經過splitText(num)便可實現節點分離。
- box.firstChild.splitText(3); //分離一個節點
除了上面的兩種方法外,Text 還提供了一些別的DOM 操做的方法以下:
- var box = document.getElementById('box');
- box.firstChild.deleteData(0,2); //刪除從0 位置的2 個字符
- box.firstChild.insertData(0,'Hello.'); //從0 位置添加指定字符
- box.firstChild.replaceData(0,2,'Miss'); //從0 位置替換掉2 個指定字符
- box.firstChild.substringData(0,2); //從0 位置獲取2 個字符,直接輸出
- alert(box.firstChild.nodeValue); //輸出結果
5.Comment 類型
Comment 類型表示文檔中的註釋。nodeType 是8,nodeName 是#comment,nodeValue
是註釋的內容。
- var box = document.getElementById('box');
- alert(box.firstChild); //Comment
PS:在IE 中,註釋節點可使用!看成元素來訪問。
- var comment = document.getElementsByTagName('!');
- alert(comment.length);
6.Attr 類型
Attr 類型表示文檔元素中的屬性。nodeType 爲11,nodeName 爲屬性名,nodeValue 爲
屬性值。DOM 基礎篇已經詳細介紹過,略。
二.DOM擴展
1.呈現模式
從IE6 開始開始區分標準模式和混雜模式(怪異模式),主要是看文檔的聲明。IE 爲
document 對象添加了一個名爲compatMode 屬性,這個屬性能夠識別IE 瀏覽器的文檔處於
什麼模式若是是標準模式,則返回CSS1Compat,若是是混雜模式則返回BackCompat。
- if (document.compatMode == 'CSS1Compat') {
- alert(document.documentElement.clientWidth);
- } else {
- alert(document.body.clientWidth);
- }
PS:後來Firefox、Opera 和Chrome 都實現了這個屬性。從IE8 後,又引入documentMode
新屬性,由於IE8 有3 種呈現模式分別爲標準模式8,仿真模式7,混雜模式5。因此若是
想測試IE8 的標準模式,就判斷document.documentMode > 7 便可。
2.滾動
DOM 提供了一些滾動頁面的方法,以下:
- document.getElementById('box').scrollIntoView(); //設置指定可見
3.children 屬性
因爲子節點空白問題,IE 和其餘瀏覽器解釋不一致。雖然能夠過濾掉,但若是隻是想
獲得有效子節點,可使用children 屬性,支持的瀏覽器爲:IE5+、Firefox3.5+、Safari2+、
Opera8+和Chrome,這個屬性是非標準的。
- var box = document.getElementById('box');
- alert(box.children.length); //獲得有效子節點數目
4.contains()方法
判斷一個節點是否是另外一個節點的後代,咱們可使用contains()方法。這個方法是IE
率先使用的,開發人員無須遍歷便可獲取此信息。
- var box = document.getElementById('box');
- alert(box.contains(box.firstChild)); //true
PS:早期的Firefox 不支持這個方法,新版的支持了,其餘瀏覽器也都支持,Safari2.x
瀏覽器支持的有問題,沒法使用。因此,必須作兼容。
在Firefox 的DOM3 級實現中提供了一個替代的方法compareDocumentPosition()方法。
這個方法肯定兩個節點之間的關係。
- var box = document.getElementById('box');
- alert(box.compareDocumentPosition(box.firstChild)); //20
PS:爲何會出現20,那是由於知足了4 和16 兩項,最後相加了。爲了能讓全部瀏覽
器均可以兼容,咱們必須寫一個兼容性的函數。
- //傳遞參考節點(父節點),和其餘節點(子節點)
- function contains(refNode, otherNode) {
- //判斷支持contains,而且非Safari 瀏覽器
- if (typeof refNode.contains != 'undefined' &&
- !(BrowserDetect.browser == 'Safari' && BrowserDetect.version < 3)) {
- return refNode.contains(otherNode);
- //判斷支持compareDocumentPosition 的瀏覽器,大於16 就是包含
- } else if (typeof refNode.compareDocumentPosition == 'function') {
- return !!(refNode.compareDocumentPosition(otherNode) > 16);
- } else {
- //更低的瀏覽器兼容,經過遞歸一個個獲取他的父節點是否存在
- var node = otherNode.parentNode;
- do {
- if (node === refNode) {
- return true;
- } else {
- node = node.parentNode;
- }
- } while (node != null);
- }
- return false;
- }
三.DOM操做內容
雖然在以前咱們已經學習了各類DOM 操做的方法,這裏所介紹是innerText、
innerHTML、outerText 和outerHTML 等屬性。除了以前用過的innerHTML 以外,其餘三個
還麼有涉及到。
1.innerText 屬性
- document.getElementById('box').innerText; //獲取文本內容(若有html 直接過濾掉)
- document.getElementById('box').innerText = 'Mr.Lee'; //設置文本(若有html 轉義)
PS:除了Firefox 以外,其餘瀏覽器均支持這個方法。但Firefox 的DOM3 級提供了另
外一個相似的屬性:textContent,作上兼容便可通用。
- document.getElementById('box').textContent; //Firefox 支持
- //兼容方案
- function getInnerText(element) {
- return (typeof element.textContent == 'string') ?
- element.textContent : element.innerText;
- }
- function setInnerText(element, text) {
- if (typeof element.textContent == 'string') {
- element.textContent = text;
- } else {
- element.innerText = text;
- }
- }
2.innerHTML 屬性
這個屬性以前就已經研究過,不拒絕HTML。
- document.getElementById('box').innerHTML; //獲取文本(不過濾HTML)
- document.getElementById('box').innerHTML = '<b>123</b>'; //可解析HTML
雖然innerHTML 能夠插入HTML,但自己仍是有必定的限制,也就是所謂的做用域元
素,離開這個做用域就無效了。
- box.innerHTML = "<script>alert('Lee');</script>"; //<script>元素不能被執行
- box.innerHTML = "<style>red;< /style>"; //<style>元素不能被執行
3.outerText
outerText 在取值的時候和innerText 同樣,同時火狐不支持,而賦值方法至關危險,他
不單替換了文本內容,還將元素直接抹去。
- var box = document.getElementById('box');
- box.outerText = '<b>123</b>';
- alert(document.getElementById('box')); //null,建議不去使用
4.outerHTML
outerHTML 屬性在取值和innerHTML 一致,但和outerText 也同樣,很危險,賦值的之
後會將元素抹去。
- var box = document.getElementById('box');
- box.outerHTML = '123';
- alert(document.getElementById('box')); //null,建議不去使用,火狐舊版未抹去
PS:關於最經常使用的innerHTML 屬性和節點操做方法的比較,在插入大量HTML 標記時
使用innerHTML 的效率明顯要高不少。由於在設置innerHTML 時,會建立一個HTML 解
析器。這個解析器是瀏覽器級別的(C++編寫),所以執行JavaScript 會快的多。但,建立和
銷燬HTML 解析器也會帶來性能損失。最好控制在最合理的範圍內,以下:
- for (var i = 0; i < 10; i ++) {
- ul.innerHTML = '<li>item</li>'; //避免頻繁
- }
- //改
- for (var i = 0; i < 10; i ++) {
- a = '<li>item</li>'; //臨時保存
- }
- ul.innerHTML = a;