浏覽器事件概述
技術一般水平有限,有什麼錯的地方,望大家指正。
當我們在浏覽網頁的時候,浏覽器可以在視覺上為我們展示出頁面還可以在行為上響應用戶的操作,浏覽器響應用戶的操作就是通過事件來完成的,浏覽器提供了事件注冊接口和事件監聽接口這樣浏覽器就可以接收用戶的行為並且進行處理了。浏覽器已經提供很多的事件包括頁面加載、鼠標事件以及鍵盤事件等,我們只需要定義好事件處理函數即可,當用戶的操作觸發這些事件時就會執行我們預先定義好的處理函數。一個行為的完整過程如下:
浏覽器在交互的過程中基本的功能就是通過事件+AJAX來完成的,浏覽器通過事件來響應用戶的行為,如果是有關數據的操作在通過AJAX來與服務器完成交互。
事件的基本使用
首先事件有三種不同的綁定方式,分別為在DOM元素中直接綁定、在JavaScript中綁定,綁定事件監聽函數。
在DOM元素中直接綁定形式如下:
<button id="demo" onclick="test('test')">button</div>
在一般情況下這可以說是最不好的一種綁定方法了,首先表現層和行為層耦合在一起,對於後期的維護帶來了極大的不便,其次必須使用全局函數,我們都知道要盡可能的減少全局變量的聲明,而且這種綁定方式是可以被覆蓋的,如果我們在JS中在為該元素綁定一個點擊處理函數,那麼在DOM元素中綁定的事件處理函數都不會執行。
function test(){ console.log("DOM"); } window.onload = function(){ var demo = document.getElementById("demo"); demo.onclick = function(){ console.log("JS"); } } //只打印JS
在JavaScript中綁定形式如下:
window.onload = function(){ var demo = document.getElementById("demo"); demo.onclick = function(){ console.log("JS"); } }
這種綁定方式的缺點在於只能注冊一個監聽函數,後面的監聽函數會覆蓋前面的監聽函數假如我們有如下的代碼:
window.onload = function(){ var demo = document.getElementById("demo"); demo.onclick = function(){ console.log("JS"); } demo.onclick = function(){ console.log("change"); } } //打印change
綁定事件監聽函數形式如下:
window.onload = function(){ var demo = document.getElementById("demo"); demo.addEventListener("click",function(){console.log("handler1")},false); demo.addEventListener("click",function(){console.log("handler2")},false); } //打印handler1 handler2
這種綁定方法可以滿足我們的要求,表現層行為層分離,一個事件可以綁定多個處理函數,除了兼容方面的問題好像就沒什麼問題了,兼容問題後面再介紹首先看一下addEventListener的用法。
addEventListener接收三個參數,第一個參數表示事件名稱,第二個參數表示事件處理函數,第三個參數表示事件是捕獲或冒泡。
第一個參數表示事件名稱在使用時就是"click"、"mousemove"不要帶有on,第二個參數表示事件的處理函數,一般稱為回調函數,可以是一個匿名函數表達式或者函數名稱,第三個參數是一個布爾值為true時表示事件捕獲為false表示事件冒泡,一般第三個參數我們都設置為false,因為在IE浏覽器下只支持事件冒泡。
addEventListener兼容問題處理
在非IE浏覽器中addEventListener是可以正常使用的在IE9及以上的版本中也是可以使用的,IE提供了一個相同功能的API就是attachEvent來保證在IE8及以下可以正常使用。attachEvent接收兩個參數第一個參數表示事件名稱需要加上on比如"onclick"、"onmousemove",第二個參數表示事件處理函數可以是一個匿名函數表達式或者函數名稱,基本使用方式如下:
window.onload = function(){ var demo = document.getElementById("demo"); demo.attachEvent("onclick",function(){console.log("handler1")}); demo.attachEvent("onclick",function(){console.log("handler2")}); }
所以在綁定事件時要同時考慮這兩種情況,我們可以自行封裝一個事件綁定函數(ele:DOM對象,e:事件名稱,callback:事件處理函數):
window.onload = function(){ var demo = document.getElementById("demo"); addEvent(demo,"click",function(){console.log("兼容測試")}); function addEvent(ele,e,callback){ ele.addEventListener?ele.addEventListener(e,callback,false):ele.attachEvent("on"+e,callback); } }
也可擴展Element的原型函數:
window.onload = function(){ var demo = document.getElementById("demo"); demo.addEventListener("click",function(){console.log("handler test")},false); } Element.prototype.addEventListener = Element.prototype.addEventListener || function(e,cb){ this.attachEvent("on"+e,cb) }
取消事件綁定
如果我們綁定事件函數之後想取消事件函數的綁定,實現起來也很簡單,如果我們使用的是JavaScript的事件綁定方式,直接給事件處理函數設置為null即可:
window.onload = function(){ var demo = document.getElementById("demo"); demo.onclick = function(){ console.log("11111") } demo.onclick = null; }
如果我們使用事件監聽函數綁定的事件可以調用取消綁定的API每一種綁定方式都有它對應的解綁方式:
addEventListener綁定的監聽函數用removeEventListener來解除綁定,該函數接同樣收三個參數第一個參數表示事件名稱,第二個參數表示事件函數的名稱,第三個參數是一個布爾值表示冒泡階段或者捕獲階段。如果綁定事件函數時第二個參數是一個匿名函數表達式的話是不能解除綁定的,只有第二參數是一個以聲明的函數的名稱才可以使用removeEventListener來解除綁定。下面的這段代碼的事件處理函數是不能解除綁定的:
window.onload = function(){ var demo = document.getElementById("demo"); demo.addEventListener("click",function(){console.log("aaaa")},false); }
要想移除事件處理函數必須使用函數聲明:
window.onload = function(){ var demo = document.getElementById("demo"); demo.addEventListener("click",handler,false); demo.removeEventListener("click",handler); function handler(){ console.log("aaaa"); } }
attachEvent綁定的監聽函數要使用detachEvent來解除綁定使用方式和addEventListener基本一致,不同點就是IE浏覽器只支持事件冒泡所以省略了第三個參數,事件名稱要加上on使用方式為:
window.onload = function(){ var demo = document.getElementById("demo"); demo.attachEvent("onclick",handler); demo.detachEvent("onclick",handler); function handler(){ console.log("aaaa"); } }
訪問事件對象
在事件處理函數中,存在一個對象記錄著事件的各種信息,這個對象只存在於事件函數執行的過程中,我們可以在事件處理函數中使用一個參數來代理事件對象,在非IE浏覽器中我們可以直接使用參數作為事件對象,在IE浏覽器中我們需要使用window.event來獲取事件對象,使用方式如下:
window.onload = function(){ var demo = document.getElementById("demo"); demo.onclick = function(e){//事件處理函數是由浏覽器來調用的,在調用時會把事件對象作為參數傳遞給事件處理函數 var e = e || window.event; console.log(e); } }
我們在事件處理函數中如果需要阻止默認事件和停止冒泡就需要用到事件對象。
在非IE浏覽器中:
e.preventDefault();//阻止默認行為 e.stopPropagation();//停止冒泡
在IE浏覽器中:
e.returnValue = false;//阻止默認行為 e.cancelBubble = true;//停止冒泡