1. 程式人生 > >JS新增事件處理函式

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物件在管理所有的事件註冊和移除