寫在前面,本文將同步發佈於Blog、掘金、segmentfault、知乎等處,若是本文對你有幫助,記得爲我獲得個人我的技術博客項目給個star哦。html
你可能作Web開發已經有一段時間,你是否有想過下列問題呢?
爲何div元素甚至是全部的html元素均可以使用addEventListener來添加事件呢?
爲何每一個DOM節點都有parentNode、firstChild、nodeType等屬性呢?
爲何每一個DOM元素都有className、classList、innerHTML等屬性呢?
爲何有些DOM元素有accessKey、contentEditable、isContentEditable等屬性呢?
爲何每一個DOM元素都有onclick、ondblclick、ondrag等屬性?
本文就是來解答這些簡單而又不「簡單」的問題。node
EventTarget 是一個由能夠接收事件的對象實現的接口,而且能夠爲它們建立偵聽器。git
Element,document 和 window 是最多見的事件目標,可是其餘對象也能夠是事件目標,好比XMLHttpRequest,AudioNode,AudioContext 等等。
許多事件目標(包括元素,文檔和 window)還支持經過 onXXX(如onclick) 屬性和屬性設置事件處理程序。github
在EventTarget上註冊特定事件類型的事件處理程序。web
EventTarget中刪除事件偵聽器。segmentfault
將事件分派到此EventTarget。app
var EventTarget = function() { this.listeners = {}; }; EventTarget.prototype.listeners = null; EventTarget.prototype.addEventListener = function(type, callback) { if (!(type in this.listeners)) { this.listeners[type] = []; } this.listeners[type].push(callback); }; EventTarget.prototype.removeEventListener = function(type, callback) { if (!(type in this.listeners)) { return; } var stack = this.listeners[type]; for (var i = 0, l = stack.length; i < l; i++) { if (stack[i] === callback){ stack.splice(i, 1); return; } } }; EventTarget.prototype.dispatchEvent = function(event) { if (!(event.type in this.listeners)) { return true; } var stack = this.listeners[event.type].slice(); for (var i = 0, l = stack.length; i < l; i++) { stack[i].call(this, event); } return !event.defaultPrevented; };
Node是一個接口,許多DOM類型從這個接口繼承,並容許相似地處理(或測試)這些各類類型。Node是一個接口,許多DOM類型從這個接口繼承,並容許相似地處理(或測試)這些各類類型。佈局
Document, Element, CharacterData (which Text, Comment, and CDATASection inherit), ProcessingInstruction, DocumentFragment, DocumentType, Notation, Entity, EntityReference
PS:在方法和屬性不相關的特定狀況下,這些接口可能返回null。它們可能會拋出異常 - 例如,當將子節點添加到不容許子節點存在的節點時。測試
返回一個表示base URL的DOMString。不一樣語言中的base URL的概念都不同。 在HTML中,base URL表示協議和域名,以及一直到最後一個'/'以前的文件目錄。this
返回一個包含了該節點全部子節點的實時的NodeList。NodeList 是「實時的」意思是,若是該節點的子節點發生了變化,NodeList對象就會自動更新。
返回該節點的第一個子節點,若是該節點沒有子節點則返回null。
返回該節點的最後一個子節點,若是該節點沒有子節點則返回null。
此處省略若干Node接口屬性,更多屬性查看這裏。
--------------------重點分割線-------------------
重點:從其父類EventTarget繼承了addEventListener、removeEventListener、dispatchEvent等方法。
將一個節點添加到指定父節點的子節點列表末尾。
返回的是一個布爾值,來表示傳入的節點是否爲該節點的後代節點。
返回調用該方法的節點的一個副本。
此處省略若干Node接口方法,更多方法查看這裏。
Element是很是通用的基類,全部 Document對象下的對象都繼承它。這個接口描述了全部相同種類的元素所廣泛具備的方法和屬性。 這些繼承自Element而且增長了一些額外功能的接口描述了具體的行爲。
PS:HTMLElement 接口是全部HTML元素的基礎接口, 而 SVGElement 接口是全部SVG元素的基本接口。
在web之外的語言,像 XUL 能夠經過 XULElement 的API,也能實現它。
全部屬性繼承至它的祖先接口 Node, 和它所擴展的接口 EventTarget, 而且從如下部分繼承了屬性ParentNode, ChildNode, NonDocumentTypeChildNode, 和Animatable.
返回元素對應的 HTMLSlotElement 接口
返回一個與該元素相關的全部屬性集合NamedNodeMap
返回該元素包含的class屬性是一個DOMTokenList.
它是一個 DOMString 表示這個元素的class.
此處省略若干Element接口屬性,更多方法查看這裏。
--------------------重點分割線-------------------
從它的父類(Node)和它父類的父類(EventTarget)繼承方法,並實現parentNode、ChildNode、NonDocumentTypeChildNode、Animatable。
此處省略若干Element接口方法,更多方法查看這裏。
方法用來獲取匹配特定選擇器且離當前元素最近的祖先元素(也能夠是當前元素自己)。若是匹配不到,則返回 null。
返回元素上一個指定的屬性值。若是指定的屬性不存在,則返回 null 或 "" (空字符串)。
參數中給出類的列表,返回一個動態的 HTMLCollection ,這裏麪包含了全部持有這些類的後代元素。
此處省略若干Element接口方法,更多方法查看這裏。
HTMLElement 接口表示全部的 HTML 元素。一些HTML元素直接實現了HTMLElement接口,其它的間接實現HTMLElement接口。
--------------------重點分割線-------------------
繼承自父接口Element和 GlobalEventHandlers的屬性。
HTMLElement.accessKey DOMString 獲取/設置元素訪問的快捷鍵
HTMLElement.accessKeyLabel DOMString 返回一個包含元素訪問的快捷鍵的字符串(只讀)
HTMLElement.contentEditable DOMString 獲取/設置元素的可編輯狀態
HTMLElement.isContentEditable Boolean 代表元素的內容是否可編輯(只讀)
此處省略若干HTMLElement接口屬性,更多方法查看這裏。
HTMLElement.onTouchStart
HTMLElement.onTouchEnd
HTMLElement.onTouchMove
HTMLElement.onTouchEnter
HTMLElement.onTouchLeave
HTMLElement.onTouchCancel
HTMLElement.blur() void 元素失去焦點
HTMLElement.click() void 觸發元素的點擊事件
HTMLElement.focus() void 元素得到焦點
HTMLElement.forceSpellCheck() void
GlobalEventHandlers接口描述了事件處理程序像HTMLElement常見的幾個接口,文件,窗口,或WorkerGlobalScope Web Workers。這些接口能夠實現更多的事件處理程序。
中斷事件。
失去焦點事件。
獲取焦點事件。
此處省略若干GlobalEventHandlers接口屬性,更多方法查看這裏。
該接口用於建立對應的元素。
如:
HTMLDivElement 接口提供了一些特殊屬性(它也繼承了一般的 HTMLElement 接口)來操做div元素。
HTMLFormElement接口能夠建立或者修改<form>對象;它繼承了HTMLElement接口的方法和屬性。
HTMLAnchorElement 接口表示超連接元素,並提供一些特別的屬性和方法(除了那些繼承自普通 HTMLElement對象接口的以外)以用於操做這些元素的佈局和顯示。
......
經過上面的知識,咱們瞭解到:
HTMLDivElement(其餘元素接口) 繼承 HTMLElement 和 GlobalEventHandlers 接口。
HTMLElement 繼承 Element 接口。
Element 繼承 Node 接口。
Node 繼承 EventTarget 接口。
爲何div元素甚至是全部的html元素均可以使用addEventListener來添加事件呢?
回答:從 EventTarget 接口中繼承而來。
爲何每一個DOM節點都有parentNode、firstChild、nodeType等屬性呢?
回答:從 Node 接口中繼承而來。
爲何每一個DOM元素都有className、classList、innerHTML等屬性呢?
回答:從 Element 接口中繼承而來。
爲何有些DOM元素有accessKey、contentEditable、isContentEditable等屬性呢?
回答:從 HTMLElement 接口中繼承而來。
爲何每一個DOM元素都有onclick、ondblclick、ondrag等屬性?
回答:從 GlobalEventHandlers 接口中繼承而來。
--------------------重點分割線-------------------
參考文檔:
EventTarget
Node
Element
HTMLElement
GlobalEventHandlers