JS新增事件處理函式
作為一種事件驅動的程式語言,Js的程式很少主動執行,一般都是由一些事件觸發,像click,dblclick,keypress,mousemove等事件,然後執行一段指令碼。給一個事件指派一個處理函式,一般稱做:註冊事件處理函式。
比如頁面上有一個p元素:
<p id=’lethe’>測試一下</p>
我們用
x = document.getElementById(’lethe’)
得到了這個結點。現在嘗試給它新增一個滑鼠點選的事件,當滑鼠點選的時候,彈出一句話:
“測試成功!”
事件處理函式很簡單:function beLessForgetfull(){ alert(”測試成功”) }
很遺憾的是,不同的瀏覽器新增事件處理函式的方法不太一樣。主要有三種:
傳統方式,把事件處理函式做為DOM元素的一個屬性,像onclick,onmouseover等。現代瀏覽器一般會相容這種寫法。
x.onclick = beLessForgetfull;
傳統方式的缺點是,不能給一個元素的一種事件定義兩個事件處理函式,因為後面新增的函式會覆蓋前面的。
高階方法:
IE系列的:attachEvent(eventType, handler)
x.attachEvent(’onclick’, beLessForgetfull);
W3CDOM定義的:addEventListener(eventType, handler, capture),多了一個capture引數,是boolean型別的。如果是false,表示事件冒泡。如果為true則表示事件捕捉。IE只支援冒泡,所以通常都是false。
x.addEventListener(’click’, beLessForgetfull, false);
優點就是,可以給一個元素一種事件註冊多個處理函式。
添加了事件處理函式,如果在不用的時候,自然應該可以移除。
傳統方式註冊的處理函式,要移除就非常簡單了。
el.onclick = null; // 移除click處理函式。
高階方法註冊了的事件處理函式,要用detachEvent或removeEventListener來移除。引數和attachEvent或addEventListener一樣。
x.detachEvent(’onclick’, beLessForgetfull);
或
x.removeEventListener(’click’, beLessForgetfull);
但是如果要移除所有的事件處理函式,因為沒有一個方法可以找到所有註冊在一個元素上的事件處理函式,所以需要寫程式的人自己去記住這些函式,然後一個一個地去除。
IE的attachEvent還有一個問題是,事件處理函式是全域性的。就是說,在事件處理函式裡,this是等於window的。
要解決這一點並不太難。這是例子:
4 function addEventSimple(evt, el, handler){
5 if(el.addEventListener){
6 el.addEventListener(evt, handler, false);
7 }else if(el.attachEvent){
8 el.attachEvent(’on’+evt, function(){
9 return handler.call(el, window.event);
10 });
11 }else{
12 //var oldHandler = el['on'+evt] || function(){};
13 el['on'+evt] = handler;
14 }
15 }
用到了函式物件的call方法,這個方法和apply方法,都是可以指定函式裡的this物件的,它們的差別只在於引數傳遞方式的不一樣。
上面的例子的最後的else部分,還沒有寫完。原先是想讓只支援傳統方式的瀏覽器也可以註冊多個事件處理函式。
不過,對於這個addEventSimple,如果要再寫一個移除事件處理函式的,就是removeEventComplex,如果只是複雜還好,似乎還是不可能的。在jQuery,似乎是用了一個$Event物件在管理所有的事件註冊和移除