前端學習:教程&開發模塊化/規範化/工程化/優化&工具/調試&值得關注的博客/Git&面試-前端資源彙總javascript
歡迎提issues斧正:Event前端
JavaScript中,事件通常是指瀏覽器和用戶操做進行交互。咱們能夠經過偵聽器(或者處理程序)來預約事件,以便事件發生的時候執行相應的代碼。java
JavaScript的事件模型有DOM0,腳本模型,DOM2&DOM3三個模型。git
DOM0模型即內聯模型,這種模型是最傳統接單的一種處理事件的方法。在內聯模型中,事件處理函數是HTML標籤的一個屬性,用於處理指定事件。雖然內聯在早期使用較多,但它是和HTML 混寫的,並無與HTML 分離。github
<input type="button" value="click me " onclick="console.log('xzavier win');" /> //點擊在打印臺輸出 xzavier win <input type="button" value="click me " onclick="func();" /> <script type="text/javascript"> function func(){ console.log('xzavier win win'); } //點擊在打印臺輸出 xzavier win win
其實世上原本沒有DOM0,叫的人多了,也就有了DOM0。1998 年 10 月 DOM1級規範成爲 W3C 的推薦標準,在此以前的實現咱們就習慣稱爲DOM0級,後來就都叫DOM0了。面試
內聯模型違反了HTML 與JavaScript 代碼層次分離的原則。腳本模型讓咱們能夠在JavaScript 中處理事件。編程
<input type="button" id="myBotton" value="click me " /> var oBotton = document.getElementById('myBotton'); oBotton.onclick = function () { console.log('xzavier win win'); }; //點擊在打印臺輸出 xzavier win win
DOM2和DOM3級別則在這個結構的基礎上引入了更多的交互能力,也支持了更高級的XML特性。爲此DOM2和DOM3級分爲許多模塊(模塊之間具備某種關聯),分別描述了DOM的某個很是具體的子集。瀏覽器
一、DOM2級核心(DOM Level 2 Core):在1級核心的基礎上構建,爲節點添加了更多方法和屬性;
二、DOM2級視圖(DOM Level 2 Views):爲文檔定義了基於樣式信息的不一樣視圖;
三、DOM2級事件(DOM Level 2 Style):定義瞭如何以編程方式來訪問和改變CSS樣式信息;
四、DOM2級遍歷和範圍(DOM Level 2 Traversal and Range):引入了遍歷DOM文檔和選擇其特定部分的新接口。
五、DOM2級HTML(DOM Level 2 HTML):在1級HTML基礎上構建,添加了更多屬性、方法和新接口。
六、DOM3級又增長了XPath模塊和加載與保存(Load and Save)模塊。框架
<input type="button" id="myBotton" value="click me " /> var oBotton = document.getElementById('myBotton'); oBotton1.addEventListener('click', function () { console.log('xzavier win win'); }); //點擊在打印臺輸出 xzavier win win
DOM2 級事件」定義了兩個方法,用於添加事件和刪除事件處理程序的操做:
addEventListener()和removeEventListener()。全部DOM 節點中都包含這兩個方法,而且它們都接受3 個參數;事件名、函數、冒泡或捕獲的布爾值(true 表示捕獲,false 表示冒泡)。模塊化
window.addEventListener('load', function () { console.log('xzavier'); }, false);
IE 實現了與DOM2 中相似的兩個方法:attachEvent()和detachEvent()。這兩個方法接受相同的參數:事件名稱和函數。
window.attachEvent('onload', function () { console.log('xzavier'); });
寫一個ready()方法,DOM結構繪製完畢後就執行,沒必要等到加載完畢,也實踐下兼容
function ready(fn){ if(document.addEventListener) { //標準瀏覽器 document.addEventListener('DOMContentLoaded', function() { //註銷事件, 避免反覆觸發 document.removeEventListener('DOMContentLoaded',arguments.callee, false); fn(); //執行函數 }, false); }else if(document.attachEvent) { //IE document.attachEvent('onreadystatechange', function() { if(document.readyState == 'complete') { document.detachEvent('onreadystatechange', arguments.callee); fn(); //函數執行 } }); } };
JavaScript 能夠處理的事件類型爲:鼠標事件、鍵盤事件、HTML 事件。
<input type="button" id="myBotton" value="click me " /> var oBotton = document.getElementById('myBotton'); click:當用戶單擊鼠標按鈕或按下回車鍵時觸發 oBotton.onclick = function () { console.log('xzavier is so ...'); }; dblclick:當用戶雙擊主鼠標按鈕時觸發 oBotton.ondblclick = function () { console.log('xzavier is so ...'); }; mousedown:當用戶按下了鼠標還未彈起時觸發 oBotton.onmousedown = function () { console.log('xzavier is so ...'); }; mouseup:當用戶釋放鼠標按鈕時觸發 oBotton.onmouseup = function () { console.log('xzavier is so ...'); }; mouseover:當鼠標移到某個元素上方時觸發 oBotton.onmouseover = function () { console.log('xzavier is so ...'); }; mouseenter:同mouseover,但子元素不會觸發 oBotton.onmouseenter = function () { console.log('xzavier is so ...'); }; mouseout:當鼠標移出某個元素上方時觸發 oBotton.onmouseout = function () { console.log('xzavier is so ...'); }; mouseleave: 同onmouseout,但子元素不會觸發 oBotton.onmouseleave = function () { console.log('xzavier is so ...'); }; mousemove:當鼠標指針在元素上移動時觸發 oBotton.onmousemove = function () { console.log('xzavier is so ...'); }; drag: 事件在元素或者選取的文本被拖動時觸發,但必須設有draggable="true" oBotton.ondrag = function () { console.log('xzavier is so ...'); }; 在拖動元素時,每隔 350 毫秒會觸發 ondrag 事件
mouseover與mouseenter
不論鼠標指針穿過被選元素或其子元素,都會觸發 mouseover 事件。只有在鼠標指針穿過被選元素時,纔會觸發 mouseenter 事件。
mouseout與mouseleave
不論鼠標指針離開被選元素仍是任何子元素,都會觸發 mouseout 事件。只有在鼠標指針離開被選元素時,纔會觸發 mouseleave 事件。
關於拖拽
在拖動目標上觸發事件 (源元素):
ondragstart - 用戶開始拖動元素時觸發 ondrag - 元素正在拖動時觸發 ondragend - 用戶完成元素拖動後觸發
釋放目標時觸發的事件:
ondragenter - 當被鼠標拖動的對象進入其容器範圍內時觸發此事件 ondragover - 當某被拖動的對象在另外一對象容器範圍內拖動時觸發此事件 ondragleave - 當被鼠標拖動的對象離開其容器範圍內時觸發此事件 ondrop - 在一個拖動過程當中,釋放鼠標鍵時觸發此事件
keydown:當用戶按下鍵盤上任意鍵觸發,若是按住不放,會重複觸發。 onkeydown = function () { console.log('xzavier is so ...'); }; keypress:當用戶按下鍵盤上的字符鍵觸發,若是按住不放,會重複觸發。 onkeypress = function () { console.log('xzavier is so ...'); }; keyup:當用戶釋放鍵盤上的鍵觸發。 onkeyup = function () { console.log('xzavier is so ...'); };
keydown返回的是鍵盤的代碼, keypress返回的是ASCII字符。若是隻想讀取字符, 用keypress, 若是想讀各鍵的狀態, 用keydown.
load:當頁面徹底加載後在window 上面觸發,或當框架集加載完畢後在框架集上觸發。 window.onload = function () { console.log('xzavier is so ...'); }; unload:當頁面徹底卸載後在window 上面觸發,或當框架集卸載後在框架集上觸發。 window.onunload = function () { console.log('xzavier is so ...'); }; select:當用戶選擇文本框(input 或textarea)中的一個或多個字符觸發。 input.onselect = function () { console.log('xzavier is so ...'); }; <input type="textarea" id="myBotton" value="click me " /> var oBotton = document.getElementById('myBotton'); change:當文本框(input 或textarea)內容改變且失去焦點後觸發。 oBotton.onchange = function () { console.log('xzavier is so ...'); }; focus:當頁面或者元素得到焦點時在window 及相關元素上面觸發。 oBotton.onfocus = function () { console.log('xzavier is so ...'); }; blur:當頁面或元素失去焦點時在window 及相關元素上觸發。 oBotton.onblur = function () { console.log('xzavier is so ...'); }; submit:當用戶點擊提交按鈕在<form>元素上觸發。 form.onsubmit = function () { console.log('xzavier is so ...'); }; reset:當用戶點擊重置按鈕在<form>元素上觸發。 form.onreset= function () { console.log('xzavier is so ...'); }; resize:當窗口或框架的大小變化時在window 或框架上觸發。 window.onresize = function () { console.log('xzavier is so ...'); }; scroll:當用戶滾動帶滾動條的元素時觸發。 window.onscroll = function () { console.log('xzavier is so ...'); };
事件對象就是event 對象,經過處理函數傳遞。
//經過處理函數傳遞事件對象 <input type="textarea" id="myBotton" value="click me " /> var oBotton = document.getElementById('myBotton'); oBotton.addEventListener('click', function (e) { //接受事件對象參數 console.log(e); });
event 對象的屬性
屬性名 描述 type 獲取這個事件的事件類型,例如:click target 獲取綁定事件的DOM 元素 data 獲取事件調用時的額外數據 relatedTarget 獲取移入移出目標點離開或進入的那個DOM 元素 currentTarget 獲取冒泡前觸發的DOM 元素,等同與this pageX/pageY 獲取相對於頁面原點的水平/垂直座標 screenX/screenY 獲取顯示器屏幕位置的水平/垂直座標(非jQuery 封裝) clientX/clientY 獲取相對於頁面視口的水平/垂直座標(非jQuery 封裝) result 獲取上一個相同事件的返回值 timeStamp 獲取事件觸發的時間戳 which 獲取鼠標的左中右鍵(1,2,3),或獲取鍵盤按鍵 altKey/shiftKey/ctrlKey/metaKey 獲取是否按下了alt、shift、ctrl或 meta 鍵
event.target 獲得的是觸發元素的DOM,event.currentTarget 獲得的是監聽元素的DOM。而this 也是獲得監聽元素的DOM。
若是在頁面中重疊了多個元素,而且重疊的這些元素都綁定了同一個事件,那麼就會出現冒泡問題。
<div id="myDiv" style="width:200px;height:200px;background:#666;"> input type="button" id="myBotton" value="click me " /> </div> var oBotton = document.getElementById('myBotton'); var oDiv = document.getElementById('myDiv'); //三個不一樣元素觸發事件 oBotton.addEventListener('click', function () { console.log('input'); }); oDiv.addEventListener('click', function () { console.log('div'); }); document.addEventListener('click', function () { console.log('document'); });
當點擊文檔的時候,只觸發文檔事件;當點擊div 層時,觸發了div 和文檔兩個;當咱們點擊按鈕時,觸發了按鈕、div 和文檔。觸發的順序是從小範圍到大範圍。這就是所謂的冒泡現象,一層一層往上冒泡觸發。
網頁中的元素,在操做的時候會有本身的默認行爲。好比:右擊文本框輸入區域,會彈出系統菜單、點擊超連接會跳轉到指定頁面、點擊提交按鈕會提交數據。咱們能夠組織默認行爲的發生
//禁止連接跳轉 $('a').click(function (e) { e.preventDefault(); }); //禁止提交表單跳轉 $('form').submit(function (e) { e.preventDefault(); });
若是想讓上面的超連接同時阻止默認行爲且禁止冒泡行爲,能夠把兩個方法同時寫上:event.stopPropagation()和event.preventDefault()。這兩個方法若是須要同時啓用的時候,還有一種簡寫方案代替,就是直接return false
$('a').click(function (e) { return false; });
冒泡和默認行爲的一些方法
方法名 描述 preventDefault() 取消某個元素的默認行爲 isDefaultPrevented() 判斷是否調用了preventDefault()方法 stopPropagation() 取消事件冒泡 isPropagationStopped() 判斷是否調用了stopPropagation()方法 stopImmediatePropagation() 取消事件冒泡,並取消該事件的後續事件處理函數 isImmediatePropagationStopped() 判斷是否調用了stopImmediatePropagation()方法
1.事件冒泡:事件按照從最特定的事件目標到最不特定的事件目標(通常爲document對象)的順序觸發。
2.事件捕獲(event capturing):事件從最不精確的對象(通常爲document 對象)開始觸發,而後到最精確(也能夠在窗口級別捕獲事件,不過必須由開發人員特別指定)。
3.DOM事件流:同時支持兩種事件模型:捕獲型事件和冒泡型事件,可是,捕獲型事件先發生。兩種事件流會觸及DOM中的全部對象,從document對象開始,也在document對象結束。
事件捕獲階段:事件從最上一級標籤開始往下查找,直到捕獲到事件目標(target)。
事件冒泡階段:事件從事件目標(target)開始,往上冒泡直到頁面的最上一級標籤。
不是全部的事件都能冒泡,例如:blur、focus、load、unload等
W3C : addEventListener('click',doSomething,true); //true=捕獲 false=冒泡 諸如onclick,onchange 事件採用事件冒泡方式 IE : attachEvent("onclick", doSomething2); 不支持捕獲,只有冒泡. 阻止事件冒泡: 在W3c中,使用stopPropagation()方法 在IE下設置cancelBubble = true; 在捕獲的過程當中stopPropagation()後,後面的冒泡過程也不會發生了~ 阻止事件的默認行爲,例如click <a>後的跳轉~ 在W3c中,使用preventDefault()方法; 在IE下設置window.event.returnValue = false;
事件委託的原理就是事件冒泡。使用事件委託技術可讓你對每一個節點添加事件監聽器,事件監聽器被添加到它們的父元素上。事件監聽器會分析從子元素冒泡上來的事件,找到是哪一個子元素的事件。
獲取點擊的元素的信息:
ul id="test"> <li>first</li> <li>second</li> <li>third</li> </ul> // 方法一: var lis = document.getElementById('test').getElementsByTagName('li'); for(var i = 0;i < 3;i++){ lis[i].index = i; lis[i].onclick = function(){ console.log(this.index); }; } // 方法二: var lis = document.getElementById('test').getElementsByTagName('li'); for(var i = 0;i < 3;i++){ lis[i].index = i; lis[i].onclick = (function(val){ return function() { console.log(val); } })(i); } // 方法三 事件委託 委託給ul var oUl = document.getElementById('test'); oUl.addEventListener('click',function(e){ var lis = e.target; console.log(lis); });
學習參考:DOM3級與事件