Javascript高級程序設計(一)DOM和BOM之DOM篇

一個完整的JavaScript實現應該由下列三個不同的部分組成:

(1)核心(ECMAScript)
(2)文檔對象模型(DOM)
(3)瀏覽器對象模型(BOM)

(一)DOM(Document Object Model)

1.DOM概念

(1)文本對象模型,是針對XML,HTML的應用程序編程接口。
(2)DOM把整個頁面映射成一個多層節點結構。也就是樹狀結構。
(3)借助DOM提供的接口,可以輕松的刪除,添加,替換和修改任何節點。
(4)在 DOM中 , 每一個元素都是節點。

整個文檔是一個文檔節點。
每個 HTML 標簽是一個元素節點
包含在 HTML 元素中的文本是文本節點
每一個 HTML 屬性是一個屬性節點
注釋屬于注釋節點

JavaScript中的所有節點類型都繼承自Node類型,因此所有節點類型都共享著相同的基本屬性和方法。
每個節點都有一個nodeType屬性,用于表明節點的類型。

常見節點類型:
常見節點類型
nodeName和nodeValue屬性

要了解節點的具體信息,可以使用這兩個屬性,不過這兩個屬性的值取決于節點的類型


nodeName和nodeValue屬性
關系節點
  • childNodes

每個節點都有一個childNodes屬性,保存著一個NodeList對象,是一種類數組對象,保存著一組子節點,并且length屬性,特點是可以基于DOM結構動態執行查詢的結果,因此DOM結構的變化能夠自動反映在NodeList對象中

注意:節點的childNodes包含了節點內的所有節點類型(不包括屬性節點),而且標簽內的換行和空格都會被當成一個文本包含在childNodes屬性中
  • parentNode

每個節點都有一個parentNode屬性,該屬性指向文檔樹種的父節點,因此,包含在childNodes列表中的所有節點都有相同的父節點,他們的parentNode屬性都指向同一個節點

  • previousSibling 和nextSibling屬性

childNodes列表中的每個元素節點相互之間都是同胞節點,可以通過每個節點的previousSibling和nextSibling屬性訪問同一列表的其他節點

  • firstChild 和lastChild屬性

在父節點下使用這兩個屬性可以分別獲取childNodes列表下的第一個和最后一個節點.為部分需求操作提供的極大的便利

  • hasChildNodes()

這個方法非常簡單實用,在節點包含一或多個子節點的情況下返回true,而無需查詢childNodes的length大小來判斷

  • ownerDocument

所有節點都有的最后一個屬性是ownerDocument,該屬性指向整個文檔的文檔節點,不用層層回溯到頂端
舉例:

<!DOCTYPE html>
<html>
<body>

<p id="demo">請點擊按鈕來獲得 <p> 元素的 ownerDocument 的節點類型。</p>

<button onclick="myFunction()">試一下</button>

<script>
function myFunction()
{
var x=document.getElementById("demo");  
x.innerHTML=x.ownerDocument.nodeType;//9
}
</script>

</body>
</html>
注意:firstChild,lastChild,nextSibling,previousSibling都會將空格或者換行當做節點處理,(除IE)

所以為了準確地找到相應的元素(其他瀏覽器)
firstElementChild,
lastElementChild,
nextElementSibling,
previousElementSibling

瀏覽器兼容:var test = div1.nextElementSibling || div1.nextSibling;
操作節點
  • appendChild(新增的節點)
    接收一個新增節點作為參數 ,用于向childNodes列表的末尾添加一個節點,并返回新增的節點

  • insertBefore(要插入的節點,作為參照的節點)
    插入節點后,被插入的節點會變成參照節點的前一個同胞節點,同時被方法返回,如果參照節點是null,那么insertBefore()和appendChild()是等同的

  • replaceChild(要插入的節點,要替換的節點)
    要替換的節點將由這個方法返回并從文檔樹種移除,同時由要插入的節點占據其位置

  • removeChild(要刪除的子節點)
    這個方法接收一個參數,即要移除的節點,并且被方法返回

    前面介紹的四個操作方法操作的都是某個節點的子節點,要使用必須先取得父節點

其他方法(所有類型節點都有)
  • cloneNode(布爾值)
    用于創建調用這個方法的節點的一個完全相同的副本,插入布爾值為true則表示深度復制,復制節點和其整個節點樹,否則為淺復制 ,只復制節點本身,復制后返回的節點文本屬于文檔所有,但成為一個"孤兒",需要添加到文檔樹中
    注意:cloneNode()方法不會復制添加到DOM節點中的Javascript屬性或者事件處理程序等

  • normalize()
    處理文檔樹中的文本節點,如果在節點的后代節點中找到空文本節點,則刪除它,如果找到相鄰的文本節點,則將它們合并為一個文本節點

<!DOCTYPE html>
<html>
<body>

<p id="demo">點擊按鈕添加文本,點擊另一個按鈕來正規化元素。</p>

<button onclick="addTextNode()">添加文本節點</button>

<button onclick="normPara()">對段落進行正規化</button>

<script>
function addTextNode()
{
var y=document.createTextNode("請再次點擊。");
var x=document.getElementById("demo");
x.appendChild(y);
var z=document.getElementById("cc");
z.innerHTML=x.childNodes.length;
}

function normPara()
{
var x=document.getElementById("demo");  
x.normalize();
var z=document.getElementById("cc");
z.innerHTML=x.childNodes.length;
}
</script>

<p>上面的段落有 <span id="cc">1</span> 個子節點。</p>

</body>
</html>
舉例

HTML的DOM樹節點包括:

  1. 元素節點:上圖中<html>、<body>、<p>都是元素節點即標簽

  2. 文本節點:向用戶展示的內容,如<li>...</li>中的javascript、Dom、CSS等文本。

  3. 屬性節點:元素屬性,如<a>標簽的鏈接屬性

Document對象:

當瀏覽器載入 HTML 文檔, 它就會成為 document 對象。

Document 對象是HTML文檔的根節點與所有其他節點(元素節點,文本節點,屬性節點, 注釋節點)。

Document 對象使我們可以從腳本中對 HTML 頁面中的所有元素進行訪問。

總結:
(1)Document 對象是 Window 對象的屬性,可通過 window.document 屬性對其進行訪問。
(2)Javascript是通過Document類型表示文檔,在瀏覽器中document對象是HTMLDocument的一個實例,表示整個頁面,而且document對象也是window對象的一個屬性,因此可以作為全局對象來訪問

從document節點中取得頁面標簽
  • document.documentElement指向HTML頁面中的<html>元素
  • document.body指向<body>元素
  • document.doctype可以取得對<!DOCTYPE>的引用
  • document.title 包含<title>元素中的文本
從document節點中取得頁面的請求信息
  • document.URL為地址欄中顯示的URL
  • document.domain為頁面的域名
    -document.referrer為連接到當前頁面的那個頁面的URL
從document節點中查找元素
  • document.getElementById("mydiv")
  • document.getElementsByTagName("img"),返回一個HTMLCollection對象,和NodeList對象類似,并且擁有一個方法namedItem()可以傳入元素的name特征來取得集合中的項,可以通過document.getElementsByTagName("*")獲取全部元素
  • document.getElementsByClassName("class"):獲取類名相同的元素,Internet Explorer 8 及更早 IE 版本不支持 getElementsByClassName() 方法
  • document.getElementsByName():這個方法會返回有給定name特征的所有元素,通常用來獲取單選按鈕.
  • document.anchors:包含文檔中所有帶name特性的a元素
  • document.forms:包含文檔中所有的form元素
  • document.images:包含文檔中所有的img元素
  • document.links:包含文檔中所有帶有href特性的a元素
文檔寫入
  • document.write(寫入字符串):將輸出流寫入到網頁
  • document.writeln(寫入字符串):將輸出流寫入到網頁并換行
    注意:必要時候要加轉義字符\
  • document.open()和document.close()分別用于打開和關閉網頁的輸出流,如果是在頁面加載期間使用write()或writeln()方法,則不需要用到這兩個方法,調用write或writeln方法時和結束時,瀏覽器會隱式調用這兩個方法

Element類型

判斷元素標簽的最佳實踐:
if(element.tagName.toLowerCase() == "div"){ //在此執行某些操作 }

HTML元素

每個HTML元素都有下列標準特性:

獲取和修改特性
  • getAttribute(特性名稱attributename)
    參數:需要獲得的屬性值的屬性名稱;
    不僅可以取得節點的默認特性也可以取得自定義特性(根據HTML5規范,自定義屬性應該加上data-前綴以便驗證),返回對應特性值
    注意:傳入style特性后返回的是包含的CSS文本,而通過屬性來訪問style則返回一個對象,因為一系列的問題原因,平時開發只使用對象的屬性來獲取特性,而只有在取得自定義特性值的情況下,才會使用getAttribute()方法

  • setAttribute(特性名稱,特性值)
    如果特性存在,則用特性值進行修改,若不存在,則新建特性并賦予特性值,該方法不僅可以操作HTML特性也可以操作自定義特性,而使用對象屬性設置的自定義特性則不會自動成為元素的特性

  • removeAttribute(要刪除的特性名稱)
    這個方法用于徹底刪除元素的特性,不僅清除特性的值也會從元素中完全刪除特性

attributes屬性

Element類型是使用attributes屬性的唯一一個DOM節點類型,elment.attributes實質是該元素節點的所有屬性節點的結合,稱為NamedNodeMap,并且擁有它自己的特殊方法:

  • getNamedItem(name) 返回nodeName屬性等于name的節點,即返回屬性名對應的屬性節點
  • removeNamedItem(name):刪除該屬性節點
  • setNamedItem(node) :向列表中添加屬性節點,以nodeName為索引
    item(po): 返回位于數字Pos位置處的節點
創建元素
  • document.createElement(元素標簽名)
    該方法可以傳入完整的元素標簽如
    var div = document.createElement("div id="myNewDiv" class = "box"></div>");
    注意:這種形式創建的動態元素有很多已知的問題,若要創建一些跟別的元素或者存在相關事件處理的元素,不推薦用這種方法,如iframe標簽 input標簽 有name相同的單選按鈕等
元素的子節點

從上面就可以發現,用元素節點的childNodes遍歷其子元素節點會出現一些換行和空格等形成了文本節點的問題,這意味著在執行某項操作之前,都要檢查一下nodeType屬性,如:

for(var i = 0,len=element.childNodes.length;i<len;i++){
 if(element.childNodes[i].nodeType == 1){ 
//執行某些操作 
} }

Text類型

  • nodeValue和data屬性:均可以用來訪問Text節點包含的文本
  • appendData(text)
  • deleteData(offset,count)
  • insertData(offset,text)
  • replaceData(offset,count,text)使用指定文本來替換此節點以及所有相鄰的文本節點,W3C標準,瀏覽器不支持
  • splitText(offset)
  • (offset,count)從節點提取數據
    length屬性返回文本字符的數目
創建文本節點

document.createTextNode(要插入節點中的文本)
作為參數的文本將按照HTML或XML的格式進行編碼

規范化文本節點

normalize()方法

分割文本節點

與normalize()方法相反的splitText(pos)方法,將一個文本節點分成兩個文本節點

DocumentFragment類型

在所有的節點類型中,只有DocumentFragment在文檔中沒有對應的標記,DOM規范規定文檔片段是一種"輕量級"的文檔,可以包含和控制節點.雖然不能把文檔片段直接添加到文檔中,但可以將它作為一個"倉庫"來使用,即可以在里面保存將來可能添加到文檔中的節點

創建文檔片段

使用document.createDocumentFragment(),返回一個文檔片段對象,繼承了Node的所有方法,可以往里面堆積節點,然后一次性添加到文檔樹中,減低瀏覽器的渲染次數

Attr類型
不常單獨使用,不過多描述

Comment類型 ,CDATASection類型 ,DocumentType類型
不常單獨使用,不過多描述

2.DOM級別

2.1 DOM1級

DOM1級由兩個模塊組成,DOM核心(DOM Core)和DOM HTML。
DOM核心規定的是如何映射基于XML的文檔結構,以便簡化堆文檔中任意部分的訪問和操作。
DOM HTML模塊則在DOM核心的基礎上加以擴展,添加了針對HTML的對象和方法。

2.2 DOM2級

DOM2級在原來的DOM基礎上又擴充了鼠標和用戶界面事件,范圍,遍歷(迭代DOM文檔的方法)等模塊,而且通過對象接口增加了對CSS的支持

DOM視圖(DOM Views):定義了跟蹤不同文檔視圖的接口。
DOM事件:描述事件接口;
DOM樣式:描述處理基于CSS樣式的接口;
DOM遍歷與范圍:描述遍歷和操作文檔樹的接口;
2.3DOM3級
進一步擴展了DOM,引入了以統一方式加載和保存文檔的方法-在DOM加載和保存(DOMLoad and Save)模板中定義
新增了驗證文檔的方法-在DOM驗證(DOM Validation)模板中定義。
DOM3級也對DOM核心進行了擴展,開始支持XML1.0規范,涉及XML Infoset,XPath和XML Base。
注意:DOM0級標準是不存在的,所謂的DOM0級只是DOM歷史坐標中的一個參照點。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容