用慣了插件,腳手架越發想了解最底層或是最初是怎么控制dom交互的,之前也看過大多不理解,要么就是硬記...
今天按照自己理解做了個筆記方便日后隨用隨取
一 DOM事件流
事件
是文檔或瀏覽器窗口中發生的一些特定的交互瞬間。JavaScript與HTML之間的交互是通過事件實現的。
事件流
是事件在目標元素和祖先元素間的觸發順序,
在早期,微軟和網景實現了相反的事件流, 網景主張捕獲方式, 微軟主張冒泡方式:
捕獲 - Capture - 事件由最頂層逐級向下傳播, 直至到達目標元素.
冒泡 - Bubble - 從下往上. 事件由第一個被觸發的元素接收, 然后逐級向上傳播.
最后 w3c 采用折中的方式, 規定先捕獲再冒泡平息了戰火. 如此一個事件就被分成了三個階段(是的, 不光是捕獲和冒泡):
捕獲階段 - The capture phase - 事件從最頂層元素 window 一直傳遞到目標元素的父元素.
目標階段 - The target phase - 事件到達目標元素. 如果事件指定不冒泡. 那就會在這里中止.
冒泡階段 - The bubble phase - 事件從目標元素父元素向上逐級傳遞直到最頂層元素 window.
在 DOM2 中, 事件監聽機制提供了一個參數來決定事件是在捕獲階段生效還是在冒泡階段生效
EventTarget.addEventListener() 方法將指定的監聽器注冊到目標元素上, 當該對象觸發指定的事件時, 指定的回調函數就會被執行.
語法
target.addEventListener(type, listener, options);
type: 表示監聽事件類型的字符串. 事件列表.
listener: 當所監聽的事件類型觸發時的回調. 會接收到一個事件通知對象.
options: 可選. 可用的選項如下:
capture: Boolean, 如果是 true, 表示 listener 會在捕獲階段觸發. 默認是 false,冒泡.
once: Boolean, 如果是 true, 表示 listener 在添加之后最多只調用一次.
passive: Boolean,如果是true, 表示 listener 永遠不會調用 preventDefault(). 如果 listener 仍然調用了這個函數, 客戶端將會忽略它並拋出一個控制台警告.
萬維網聯盟(w3c)World Wide Web Consortium創建於1994年,是Web技術領域最具權威和影響力的國際中立性技術標准機構.
二 DOM級別
文檔對象模型 (DOM) 是一個平台,一個中立於語言的應用程序編程接口 (API),允許程序訪問並更改文檔的內容、結構和樣式。
DOM 級別 0,不是 W3C 規范。而僅僅是對在 Netscape Navigator 3.0 和 Microsoft Internet Explorer 3.0 中的等價功能性的一種定義。
DOM 發展過程中的關鍵角色有:ArborText、IBM、Inso EPS、JavaSoft、Microsoft、Netscape、Novell、the Object Management Group、SoftQuad、Sun Microsystems 以及 Texcel。W3C 的 DOM 級別 1 建立於此功能性之上。
DOM 級別 1 專注於 HTML 和 XML 文檔模型。它含有文檔導航和處理功能。DOM 級別 1 於 1998 年 10 月 1 日成為 W3C 推薦標准。
DOM 級別 2 對 DOM 級別 1 添加了樣式表對象模型,並定義了操作附於文檔之上的樣式信息的功能性。DOM 級別 2 同時還定義了一個事件模型,並提供了對 XML 命名空間的支持
DOM 級別 3 DOM Level 3 規定了內容模型 (DTD 和 Schemas) 和文檔驗證。同時規定了文檔加載和保存、文檔查看、文檔格式化和關鍵事件.
對應的 DOM 事件
Html 事件處理程序(最早): |
<button type="button" onclick="fn" id="btn"> 點我試試 </button> <script> function fn() { alert('Hello World'); } </script>
缺點就是HTML與JS強耦合,當我們一旦需要修改函數名就得修改兩個地方 |
|
DOM0級事件處理 通過JS獲取到了這個id的按鈕,並將一個函數賦值給了一個事件處理屬性onclick;解綁事件
缺點在於一個處理程序無法同時綁定多個處理函數 |
<button id="btn" type="button"></button> <script> var btn = document.getElementById('btn'); btn.onclick = function() { alert('Hello World'); } // btn.onclick = null; 解綁事件 </script> |
DOM2級事件 定義了addEventListener和removeEventListener用來綁定和解綁事件,方法中含3個參數:綁定的事件處理屬性名稱(不包含on)、處理函數和是否在捕獲時執行事件處理函 IE8級以下版本不支持,需要用attachEvent和detachEvent來實現 |
<button id="btn" type="button"></button> <script> var btn = document.getElementById('btn'); function showFn() { alert('Hello World'); } btn.addEventListener('click', showFn, false); // btn.removeEventListener('click', showFn, false); 解綁事件 </script>(IE8級以下版本只支持冒泡型事件) btn.attachEvent('onclick', showFn); // 綁定事件 btn.detachEvent('onclick', showFn); //解綁事件 |
DOM3級事件 在DOM2級事件的基礎上添加了更多的事件類型,全部類型如下: UI事件,當用戶與頁面上的元素交互時觸發,如:load、scroll 焦點事件,當元素獲得或失去焦點時觸發,如:blur、focus 鼠標事件,當用戶通過鼠標在頁面執行操作時觸發如:dbclick、mouseup 滾輪事件,當使用鼠標滾輪或類似設備時觸發,如:mousewheel 文本事件,當在文檔中輸入文本時觸發,如:textInput 鍵盤事件,當用戶通過鍵盤在頁面上執行操作時觸發,如:keydown、keypress 合成事件,當為IME(輸入法編輯器)輸入字符時觸發,如:compositionstart 變動事件,當底層DOM結構發生變化時觸發,如:DOMsubtreeModified 同時DOM3級事件也允許使用者自定義一些事件。 |
三 獲取DOM節點
1.通過元素類型的方法來獲取DOM節點:
document.getElementById(“id”) id名,較少使用,一般只用在頂級層 |
|
document.getElementsByTagName(“p”)[i] |
標簽名 |
document.getElementsByClassName(“class”)[i] |
類名,常用 |
document.getElementsByName(“name”)[i] |
name屬性值,一般不用 |
document.querySelector(“.class”)(第一個) css選擇符模式,與之匹配的第一個元素,如果沒找到,則返回null |
|
document.querySelectorAll(“.class”)[i] |
結果為一個類數組 |
注意:document節點下調用這些方法,當然也可以在其他的元素節點下調用;最后兩個為靜態的,不是實時的,保存的是當時的狀態,是一個副本. |
2.根據關系樹來選擇(遍歷節點樹/元素節點數)
① 節點(DOM文檔對象模型):
可以將任何HTML、XML文檔描繪成一個多層次的節點樹。所有的頁面都表現為以一個特定節點為根節點的樹形結構。html文檔中根節點為document節點。
所有節點都有nodeType屬性,通過nodeType屬性可以來判斷節點的類型。
節點主要有以下幾種類型:
Element類型(元素節點):nodeType值為 1
Text類型(文本節點):值為 3
Comment類型(注釋節點):值為 8
Document類型(document節點):值為 9;其規定的一些常用的屬性有
document.body document.head 分別為HTML中的 <body><head>
document.documentElement為<html>標簽
節點都有hasChildNodes()方法判斷有無子節點,有一個或多個子節點時返回true
通過一些屬性可以來遍歷節點樹:
parentNode |
獲取所選節點的父節點,最頂層的節點為#document |
firstChild |
獲取所選節點的第一個子節點 |
childNodes |
獲取所選節點的子節點們 |
lastChild |
獲取所選節點的最后一個子節點 |
nextSibling |
獲取所選節點的后一個兄弟節點 列表中最后一個節點的nextSibling屬性值為null |
||
previousSibling |
獲取所選節點的前一兄弟節點 列表中第一個節點的previousSibling屬性值為null |
② 由於文檔中的節點類型較多,遍歷子節點的結果很多時候並不能得到我們想要的結果,使用遍歷元素節點則很方便
parentElement //返回當前元素的父元素節點(IE9以下不兼容)
children // 返回當前元素的所有子節點
firstElementChild //返回的是第一個元素子節點(IE9以下不兼容)
lastElementChild //返回的是最后一個元素子節點(IE9以下不兼容)
nextElementSibling //返回的是后一個兄弟元素節點(IE9以下不兼容)
previousElementSibling //返回的是前一個兄弟元素節點(IE9以下不兼容