前端的發展史中,咱們邏輯語言,曾經一度以「js」(Javascript )稱呼。後來,隨着前端的發展以及單頁面架構到來,前端的邏輯逐漸以「es」(ECMAScript)稱呼。html
那麼,js跟es(或es6)之間,有什麼關係呢?答案是:js = es + bom + dom。前端
咱們的文本節點之類,包括nodeType,nodeList,childNodes都屬於dom的範疇。 可能你會以爲nodeType,nodeList,childNodes等知識點,他並非那麼重要。平常工做中幾乎沒用到過。筆者就在學習vue源碼,虛擬dom轉換成html時候遇到一些問題,都是經過本文的要點去解決的,仍是須要能深入分析。vue
筆者以前已經彙總了es6差很少2W字的總結,本文再對曾經js的一部分,bom跟dom進行詳細的總結。node
咱們先來看看他們的概念:es6
DOM:文檔對象模型(Document Object Model,簡稱DOM),描述了處理網頁內容的方法和接口。最根本對象是document(window.document)。面試
BOM:瀏覽器對象模型(Browser Object Model),描述了與瀏覽器進行交互的方法和接口。由navigator、history、screen、location、window五個對象組成的,最根本對象是window。api
字面意思相對好理解。若是仍是對概念模棱兩可,好吧,這就是我寫彙總的意義,彙總成本身方便理解的語言,也許個人理解有利於你對知識點的加深。數組
DOM就是咱們平常對Html全部文本節點,元素,屬性等操做,訪問,修改等,都在dom的範疇。 其中,咱們平常用的HTML DOM,他包括HTML的標準對象模型,W3C 標準等規範。瀏覽器
而BOM,就是跟瀏覽器有關的相關是屬性,如瀏覽器的窗口呀,瀏覽器的頁面跳轉等。服務器
看到這裏,入行不深的小夥伴,可能都以爲很是簡單。其實否則,頗有學問。咱們繼續往下看。
首先咱們談談節點。
HTML文檔中的全部內容都是節點,好比body之間就是一個節點,div與/div之間也是一個節點,甚至註釋也算是註釋節點。 通常在最外層,因此html也稱根節點。
那麼可見一個常規頁面的節點是很是多的,並且他們還各自有交互關係,好比子父節點,兄弟節點,那麼WC3定義如何來訪問,修改他們呢。下面列舉經常使用方法:
getElementById() 返回帶有指定 ID 的元素。
getElementsByTagName() 返回包含帶有指定標籤名稱的全部元素的節點列表(集合/節點數組)。
getElementsByClassName() 返回包含帶有指定類名的全部元素的節點列表。
appendChild() 把新的子節點添加到指定節點。
removeChild() 刪除子節點。
replaceChild() 替換子節點。
insertBefore() 在指定的子節點前面插入新的子節點。
createAttribute() 建立屬性節點。
createElement() 建立元素節點。
createTextNode() 建立文本節點。
getAttribute() 返回指定的屬性值。
setAttribute() 把指定屬性設置或修改成指定的值。
innerHTML - 節點(元素)的文本值
parentNode - 節點(元素)的父節點
childNodes - 節點(元素)的子節點
attributes - 節點(元素)的屬性節點
這是關於最簡單的訪問或者修改的方法。
那麼節點自己包含了什麼呢
這裏包含三個內容。nodeType、nodeName、nodeValue。
首先,nodeType,是屬性返回節點的類型。nodeType 是隻讀的。咱們列舉一下文本的類型。
元素類型 | NodeType |
---|---|
元素 | 1 |
屬性 | 2 |
文本 | 3 |
註釋 | 8 |
文檔 | 9 |
須要普及一下,這裏每一個節點都有一個childNodes屬性,裏邊是一個NodeList對象(類數組),它是基於DOM結構動態執行查詢的結果,所以 DOM 結構的變化可以自動反映在NodeList對象中。
一樣每一個節點還有一個children的屬性,它與childNodes的區別就是,childNodes存儲的是NodeList對象,而children返回的是HTMLCollection對象。NodeList存儲的不僅是元素節點,也有文本節點、註釋節點等等,而HTMLCollection存儲的只有元素節點。
咱們經過案例來分析:
<div id="test">
hello <span>word</span>
</div>
<script>
let btn = document.getElementById("test");
console.log(btn.childNodes, btn.children)
//NodeList(3) [text, span, text]
//HTMLCollection(1) [span]
</script>
複製代碼
還有一點須要普及的是,不管是children仍是childNodes,他都不是真正意義的數組(關於數組,筆者ES6的總結array中已經詳細介紹過,本文再也不詳寫),是個類數組。
若是須要轉換成數組,咱們只能把獲取到的NodeList或者HTMLCollection手動轉換成數組。
咱們NodeList仍是HTMLCollection都不是數組,若是咱們須要轉化爲數組,咱們可使用擴展運算符來操做:
const array = [...NodeList]
const array2 = [...HTMLCollection]
複製代碼
介紹到這裏,你能想象一下vue的虛擬dom是怎麼操做的嗎?簡單的來講,他就是利用object對象去模擬NodeList。
屬性名nodeName
屬性名並不僅是存在與屬性節點,任何節點都有屬性名。nodeName 屬性規定節點的名稱。他們的屬性名以下:
屬性值nodeValue
nodeValue 屬性規定節點的值,也就是每一個屬性名,就有會他對應的屬性值。
屬性節點
咱們再來看一下屬性節點。什麼是屬性?咱們元素中的內置對象,就是屬性節點。好比style,class, id,都稱爲元素的屬性節點。
好比咱們須要重置元素class的值,咱們就能夠經過setAttribute從新給class賦值。 固然還有一個內置class對象能夠操做:Element.classList.add("active", "show")
介紹到這裏,你能想象一下vue的的v-if或者v-on是怎麼實現的嗎?簡單的來講,他就是把他當成一個元素屬性,獲取到對應的標識,再去解析。
再普及一下dom的事件,咱們平常用到的點擊,鼠標等事件,就是dom事件。onclick,onchange,onmousedown, onmouseup,onfocus等等,他都是一個dom事件。
這裏須要給你們普及一下關於dom事件的一些冷知識點或者細節:
js若是定製了onclick事件,會直接覆蓋掉原來標籤的onclick事件。以下邊栗子,test就失效了。
<div id="btn" onclick="test(this)"> 按鈕 </div>
let btn = document.getElementById("btn");
btn.onclick = function (e) {
alert("2");
}
function test(){
alert("1");
}
複製代碼
2.onclick的觸發來自監聽自己,而監聽事件addEventListener還須要檢測事件的迴流,因此優先級永遠都是:onclick>addEventListener, 以下邊栗子:
<div id="btn" onclick="test(this)"> 按鈕 </div>
<script>
let btn = document.getElementById("btn");
btn.onclick = function (e) {
alert("1");
}
btn.addEventListener("click", function (e) {
alert("2");
})
</script>
複製代碼
執行1再執行2.
3.獲取的對象中,currentTarget表示當前對象,而target表示事件的對象。 以下邊栗子:
let btn_box = document.getElementById("btn_box");
btn_box.addEventListener("click", function (e) {
consloe.log( e.currentTarget);
consloe.log( e.target);
})
複製代碼
點擊按鈕0, currentTarget對象指的是btn_click_0,而target對象是btn_box
除了官方自帶的click,focus等事件能夠監聽以外,咱們還能夠自定義事件進行監聽。舉個栗子:
// createEvent建立事件
let myEvent = document.createEvent('Event');
// 定義事件名爲'build'.
myEvent.initEvent('', true, true);
//eventType:事件名稱
//canBubble:是否支持冒泡
//cancelable:是否能夠用 preventDefault() 方法取消事件。
new3Event.name = "document.createEvent建立的自定義事件"
// 若是須要監聽事件
document.addEventListener('myEventName', function (e) {
// e.target matches elem
alert(e.name)
}, false);
// 觸發對象能夠是任何元素或其餘事件目標
document.dispatchEvent(myEvent);
複製代碼
這是最簡單的建立」自定義事件「的方法,document.createEvent。
若是你還須要自定義傳參數的話,可使用CustomEvent或者Event.這裏不作詳細介紹。
看完上邊的demo,咱們貌似知道了大概的用法。可是他的帶來的好處是什麼?
自定義事件的優缺點
優缺點有點相似傳統的監聽事件。其優勢就是,各模塊之間低耦合,互不影響。
缺點的話,很差定位問題,容易致使詭祕的錯誤。大項目出錯時,連入口都很難定位在哪裏。
接下來談談bom的知識點。
bom的知識點,相對的話只是知識面的瞭解。由於屬於應用開發範疇(瀏覽器開發),咱們只須要對他的知識面有所瞭解,建議不深刻。
該部分,若有面試或者平常也不會挖深,只考慮是否瞭解知識點
他能夠由下邊6部分組成:
下邊爲Location的屬性
屬性 | 描述 | 栗子 |
---|---|---|
hash | 獲取錨點,簡單來講就是url的#後邊 | #detail?a=1 |
host | url的端口 + 端口 | www.baidu.com:8080 |
hostname | 主機路徑 | www.baidu.com |
href | 完整url | www.baidu.com?a=1 |
pathname | 返回當前 URL 的路徑部分 | /index.html |
port | 端口 | 8080 |
protocol | 協議 | http或htttps |
search | 協議 | 獲取參數,簡單來講就是url的?後邊 |
下邊爲Location的方法
方法 | 描述 |
---|---|
assign | 加載新的文檔 |
reload | 從新刷新頁面 |
replace | 用新的文檔替換當前文檔 |
屬性 | 說明 |
---|---|
appCodeName | 返回瀏覽器的代碼名 |
appName | 返回瀏覽器的名稱 |
appVersion | 返回瀏覽器的平臺和版本信息 |
cookieEnabled | 返回指明瀏覽器中是否啓用 cookie 的布爾值 |
platform | 返回運行瀏覽器的操做系統平臺 |
userAgent | 返回由客戶機發送服務器的user-agent 頭部的值 |
屬性 | 說明 |
---|---|
availHeight | 返回屏幕的高度(不包括Windows任務欄) |
availWidth | 返回屏幕的寬度(不包括Windows任務欄) |
colorDepth | 返回目標設備或緩衝器上的調色板的比特深度 |
height | 返回屏幕的總高度 |
pixelDepth | 返回屏幕的顏色分辨率(每象素的位數) |
width | 返回屏幕的總寬度 |
屬性 | 說明 |
---|---|
back | 返回上一頁 |
forward | 返回下一頁 |
go | 加載 history 列表中的某個具體頁面 |
該文章除了api文檔參考第三方,其餘均爲原創。 若有錯誤之處,往留言指出。 如對你有少量幫助,請點贊與關注,後續即將持續更新文章。