在文章開始之初,我要先提一下籠統地講,什麼是DOM,什麼是BOM ,因為這篇文章最終面向的是有一定JavaScript基礎,但是對DOM和BOM並不了解,甚至不知道的朋友。
但是,在聊什麼是DOM,什麼是BOM之前,請容我先把整個的Javascript的結構給大家展示一下:
上面這張圖,我們可以看到有四個元素:JavaScript,ECMAScript,DOM和BOM ,那麼它們四個之間有什麼關聯呢?用一個式子總結它們之間的關係:
JavaScript = ECMAscript + BOM + DOM
下面我們來一個一個對它們進行一個概述:
ECMAscript:
ECMAScript 是一種由ECMA國際(前身為歐洲計算機製造商協會)通過ECMA- 262 標準化的腳本程式設計語言,它是JavaScript(簡稱JS)的標準,而瀏覽器就是要執行這個標準。
ECMAscript比較像是規定,規定了各個瀏覽器怎麼樣去執行JavaScript的語法,因為我們知道JavaScript是運行在瀏覽器上的腳本語言!有了規定,但我們還缺少與頁面中各個元素互動的方式,此時下面的DOM誕生了!
DOM:
DOM( Document Object Model ,文檔物件模型)一種獨立於語言,用於操作xml,html文檔的應用程式介面。
對於JavaScript:為了能夠讓JavaScript操作Html , JavaScript就有了一套自己的DOM程式介面。
一句話概括: DOM為JavaScript提供了一個存取和操作HTML元素的"方法" (之所以不用接口這個詞,是怕一些朋友看到接口就發怵的情況,但其實最準確的描述是給JavaScript提供了介面)
BOM:
BOM 是Browser Object Model,瀏覽器物件模型。 BOM 是為了控制瀏覽器的行為而出現的介面。
對於JavaScript:為了能讓JavaScript能控制瀏覽器的行為, JavaScript就有了一套自己的BOM介面。
一句話概括: BOM為JavaScript提供了一個控制瀏覽器行為的"方法"。
最後,上面的三個JavaScript的組成成分中, ECMscript是一種規範,而其餘的兩個都是提供了"方法",分別對應HTML元素和瀏覽器,於是下面我們針對後面兩個:DOM和BOM ,進行系統的講解,由於面向小白,我後面的講解會盡可能的簡單易懂,基礎不好也盡可放心食用!
首先我們先講解DOM的相關知識,我把它又分了兩塊內容:
好的,那什麼叫DOM樹?
或許一些學過DOM的初學者聽到這個詞也會有一點陌生,但其實DOM樹並不是什麼特別奇幻的東西,恰恰相反,對前端工作人員來說, DOM樹就是你天天處理的頁面的HTML元素所構成那顆樹:
BOM樹中,每個節點可以有兩個身分:可以是父節點的子節點,也可以是其他子節點的父節點,下面我們一起觀察下面這段程式碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>DOM_demo</title> </head> <body> <p> <a href="https://blog.csdn.net/qq_52736131">跳探戈的小龍蝦</a> </p> </body> </html>
上面的程式碼,它的DOM樹應該是這樣的:
這時候有人要問了,你說這麼半天的DOM樹,跟操作html元素有關嗎?
答案是非常有關,而且只有了解了文件的DOM樹結構,才能準確而有效的操作DOM元素,否則會出現各種意料之外的bug。在我們操作一個頁面的HTML元素之前,要對整個頁面的DOM有一個清晰的繪圖,即使在不實實在在繪圖,也要在腦中有一個清晰的脈絡結構。
關於JavaScript中DOM的一些常見的操作html元素的方法,我又雙叒叕分成幾個子部分給大家歸類介紹:
//1.通過元素的id屬性值來取得元素,回傳的是一個元素物件var element = document.getElementById(id_content) //2.透過元素的name屬性值來取得元素,傳回的是一個元素物件的陣列var element_list = document.getElementsByName(name_content) //3.透過元素的class屬性值來取得元素,傳回的是一個元素物件的陣列var element_list = document.getElementsByClassName(class_content) //4.透過標籤名稱取得元素,傳回的是一個元素物件陣列var element_list = document.getElementsByTagName(tagName)
//1.取得元素的屬性值,傳參自然是屬性名,例如class、id、href var attr = element.getAttribute(attribute_name) //2.設定元素的屬性值,傳參自然地是元素的屬性名稱及要設定的對應的屬性值element.setAttribute(attribute_name,attribute_value)
//1.建立一個html的元素,傳參是元素類型,例如p、h1-5、a,下以p為例var element = document.createElement("p") //2.建立一個文字節點,傳參的是對應的文字內容(注意是文字節點,不是某個html元素) var text_node = document.createTextNode(text) //3.建立一個屬性節點,傳參是對應的屬性名稱var attr_node = document.createAttribute(attribute_name) element.setAttributeNode(attr_node)
特別注意第三個,創建屬性節點這個方法,要搭配具體的元素,也就是你要先獲取某個具體元素element,創建一個屬性節點,最後對這個元素添加這個屬性節點( setAttributeNode) 。
//1.在element內部的最後面加入一個節點,傳入的參數是節點類型element.appendChild(Node) //2.在element內部某個已存在的節點的前面插入一個節點,仍然傳入一個節點類型的參數element.insertBefore(new_Node,existed_Node)
注意,在新增節點之前,你要先建立好節點,同時要選好父節點element ,第二個方法甚至你還要找好插入位置後面的兄弟節點。
//刪除element內的某個節點,傳參是節點類型參數element.removeChild(Node)
注意,刪除時,要找到對應的父節點element才可以順利刪除。
最後是一些常見的DOM屬性:
//1.取得目前元素的父節點var element_father = element.parentNode //2.取得目前元素的html元素型子節點var element_son = element.children //3.取得目前元素的所有類型子節點,包括html元素、文字和屬性var element_son = element.childNodes //4.取得目前元素的第一個子節點var element_first = element.firstChild //5.取得目前元素的前一個同級元素var element_pre = element.previousSibling //6.取得目前元素的後一個同級元素var element_next = element.nextSibling //7.取得目前元素的所有文本,包含html原始碼和文本var element_innerHTML = element.innerHTML //8.取得目前元素的所有文本,不包含html源碼var element_innerTEXT = element.innerText
其中,第七個的意思是說把元素內的html代碼和文本都轉成文本,原先的html代碼是執行的,轉成文字就等於變成了普通的字串!
下面我們再講一講BOM,由於篇幅有限,BOM不做特別細緻的講解(實用性的確也沒有DOM那麼大)。我們回顧一下開始的時候關於BOM的介紹:
BOM給JavaScript提供用來操作瀏覽器的若干的"方法"
那麼首先我們用一張圖把整個BOM的結構給大家梳理一下,與DOM類似,BOM也有一個樹狀結構:
從上面這張圖上,我們可以看到:
window是整個BOM樹食物鏈的頂端,因此每一個新開啟的窗口,都被認為是一個window物件。
window物件有以下常見的屬性與方法:
屬性/方法 | 意義 |
opener | 目前視窗的父視窗 |
length | 視窗中的框架數 |
document | 視窗中目前顯示的文件物件 |
alert(string) | 建立警告對話框,顯示一則訊息 |
close() | 關閉視窗 |
confirm() | 建立一個需要使用者確認的對話框 |
open(url,name,[options]) | 開啟一個新視窗並回傳新window 物件 |
prompt(text,defaultInput) | 建立一個對話方塊要求使用者輸入訊息 |
setInterval(expression, milliseconds) | 經過指定時間間隔計算一個表達式 |
setInterval(function,millis enconds,[arguments]) | 經過指定時間間隔後調用一個函數 |
setTimeout(expression,milli seconds) | 在定時器超過後計算一個表達式 |
setTimeout(expression,milli seconds,[arguments]) | 在定時器超過時後計算一個函數 |
其中,大家看到上面有一個函數alert() ,因為大家學JavaScript的時候,輸入輸出流大家大部分都以alert()函數彈窗作為自己的第一個demo ,所以看到這裡你可能會問了:
當時用alert()函數的時候,好像沒有提到window ,那這裡的alert()是之前學過的那個alert()嗎?答案是這樣的:
這兩個alert()確實是同一個函數,之所以可以不加window是因為, window的所有屬性和方法,都可以有兩種表示方法:
(1) window.屬性/ window.方法()
(2) 直接屬性/ 方法() 的方式呼叫
不只是alert(),上面所有的window屬性和函數都成立,有興趣的小夥伴可以自行嘗試。
什麼是location物件?
location物件是window物件的屬性,提供了與目前視窗中載入的文件有關的信息,也提供了一些導覽功能。
location物件有以下常見的屬性與方法:
屬性/方法 | 內容 |
host | 主機名稱:連接埠號碼 |
hostname | 主機名稱 |
href | 整個URL |
pathname | 路徑名稱 |
port | 連接埠號碼 |
protocol | 協定部分 |
search | 查詢字串 |
reload() | 重載目前URL |
repalce() | 用新的URL 取代目前頁面 |
其實我們仔細觀察上面那張結構圖就會發現:
location物件不只是window物件的一個屬性,還是document物件的屬性。
這意味著:
window.location = location = document.location
什麼是history物件?
history 物件是window 物件的屬性,它保存使用者上網的記錄,而這個記錄的時間戳記是從視窗開啟的那一刻算起。
history物件有以下常見的屬性與方法:
屬性/方法 | 描述 |
length | history 物件中的記錄數 |
back() | 前往瀏覽器歷史條目前一個URL,類似後退 |
forward() | 前往瀏覽器歷史條目下一個URL,類似前進 |
go (num) | 瀏覽器在history 物件中向前或向後 |
最後介紹一下navigator物件:
navigator對象,是BOM中辨識客戶端瀏覽器的一個window屬性。
與navigator相關的一些常見屬性:
屬性 | 說明 |
appName | 完整的瀏覽器名稱和版本資訊 |
platform | 瀏覽器所在的系統平台 |
plugins | 瀏覽器中安裝的插件資訊的陣列 |
userAgent | 瀏覽器的使用者代理字串 |
userLanguage | 作業系統的預設語言 |