事件處理程序

事件就是用戶或瀏覽器自身執行的某種動作,例如click、load等,都是事件的名字,響應事件的函數叫做事件處理程序,事件處理程序的名字以“on”開頭,例如click事件的事件處理程序就是onload。

HTML事件處理程序

每個元素支持的每種事件,都可以使用一個與相應事件處理程序同名的HTML特性來指定。例如:要讓按鈕被單擊時執行一些javascript,代碼如下:

<script type="text/javascript">
      function showMessage(){
          alert("hello world!");
      }
<input type="button" value="Click Me" onclick="showMessage()" />

showMessage()函數是在一個獨立的<script>元素中定義的,也可以包含在一個外部文件中,這樣做有一些特點:

  • 獨到之處
  1. 會創建一個封裝著元素屬性值的函數,這個函數中有一個局部變量event(事件對象)
  2. 在這個函數內部,this值等于事件的目標元素
  • 問題
  1. 存在時差問題
  2. 這樣擴展事件處理程序的作用域鏈在不同的瀏覽器會導致不同結果
  3. HTML與javascript代碼緊密耦合,如果要更換事件處理程序,則要改動HTML代碼和javascript代碼兩個部分(因為js代碼和元素是對應的),所以開發人員從HTML事件處理程序轉向使用Javascript指定事件處理程序。

DOM0級事件處理程序

通過JavaScript指定事件處理程序的傳統方法,就是將一個函數賦值給一個事件處理程序屬性。

  • 每個元素(包括window和document)都有自己的事件處理程序屬性,這些屬性通常全部小寫,如onclick。將這種屬性的值設為一個函數,就可以指定事件處理程序。
 var btn=document.getElementById("myBtn");
         btn.onclick=function(){
            alert("Clicked");
         };

注意:在這些代碼運行前不會指定事件處理程序,因為如果這些代碼在頁面中位于按鈕后面,就有可能在一段時間內怎么點擊都沒有反應。

  • 使用DOM0級方法指定的事件處理程序被認為是元素的方法。因此,這時候的事件處理程序是在元素的作用域中運行;換句話說,程序的this引用當前元素。可以在事件處理程序中通過this訪問元素的任何屬性和方法。
 var btn=document.getElementById("myBtn");
       btn.onclick=function(){
             alert(this.id);//"myBtn"
       };

注意:這種方式添加的事件處理程序會在事件流的冒泡階段被處理。

  • 可以刪除通過DOM0級方法指定的事件處理程序: btn.onclick=null; //刪除事件處理程序
    如果使用的是HTML指定時間處理程序,那么onclick屬性的值就是一個包含著在同名HTML特性中指定的代碼的函數。將相應的屬性設為null,也可以刪除以這種方式指定的事件處理程序。

DOM2級事件處理程序

DOM2級事件定義了兩個方法,用于處理指定和刪除事件處理程序的操作:addEventListener()removeEventListener()。所有DOM節點都包含這兩個方法,并且他們都接受3個參數。要處理的事件名、作為事件處理程序的函數和一個布爾值。布爾值中true表示在捕獲階段調用事件處理程序;false表示在冒泡階段調用事件處理程序。如果不是特別需要,不建議在事件捕獲階段注冊事件處理程序。

  • 用DOM2級方法添加事件處理程序的好處是可以添加多個事件處理程序:
    var btn=document.getElementById("myBtn");
            btn.addEventListener("click",function(){
                alert(this.id);
            },false);
            btn.addEventListener("click",function(){
                alert("Hello world!");
            },false);

這兩個事件處理程序會按照添加它們的順序觸發

  • 通過addEventListener()添加的事件處理程序只能通過removeEventListener()方法移除。移除時傳入的參數與添加時傳入的參數要相同。這也意味著通過addEventListener()添加的匿名函數無法移除。
    var btn=document.getElementById("myBtn");
            btn.addEventListener("click",function(){
                alert(this.id);
            },false);
            btn.removeEventListener("click",function(){
                alert(this.id);
            },false);//沒有用!看似傳入了相同的參數,其實這里的第二個參數與addEventListener()中的第二個參數是完全不同的函數

因此應該像下面這種寫法:

    var btn=document.getElementById("myBtn");
           var handler=function(){
               alert(this.id);
           };
            btn.addEventListener("click",handler,false);
            btn.removeEventListener("click",handler,false);

IE事件處理程序

IE實現了與DOM中類似的兩個方法:attachEvent()和detachEvent()。這兩個方法接收相同的兩個參數:事件處理程序名稱和事件處理程序函數。由于IE8及更早版本只支持事件冒泡,所以通過attachEvent()添加的事件處理程序都會被添加到冒泡階段。

     var btn=document.getElementById("myBtn");
            btn.attachEvent("onclick",function(){   //是onclick,而非addEventListener()的click
                 alert(this.id);
             });
  • 在IE中使用attachEvent()與使用DOM0級方法的主要區別是事件處理程序的作用域。DOM0中是在元素的作用域內運行;在attachEvent()中是在全局作用域內運行,因此this=window。
    1 var btn=document.getElementById("myBtn");
    2         btn.attachEvent("onclick",function(){
    3              alert(this===window);  //true
    4          });
  • 與addEventListener()類似,attachEvent()也可以用來為一個元素添加多個事件處理程序。不同的是attachEvent()不是以添加事件的順序執行,而是以相反的順序執行。
  • 同樣的用attachEvent()添加的事件如果是匿名函數則不能移除,否則可以用detachEvent()方法移除。

跨瀏覽器的事件處理程序

使用能力檢測來隔離瀏覽器的差異。要保證處理事件的代碼能在大多數瀏覽器下一致的運行,只需關注冒泡階段。

    var EventUtil={
       //視情況分別使用DOM0級方法、DOM2級方法、IE方法來添加/刪除事件,需要3個參數:
        要操作的元素、事件名稱、事件處理程序函數。
            addHandler:function(element,type,handler){
                if(element.addEventListener){
                    element.addEventListener(type,handler,false);
                } else if(element.attachEvent){
                    element.attachEvent("on"+type,handler);
                } else{
                    element["on"+type]=handler;
                }
            },
            removeHandler:function(element,type,handler){
                if(element.removeEventListener){
                    element.removeEventListener(type,handler,false);
                } else if(element.detchaEvent){
                    element.detchaEvent("on"+type,handler);
                } else{
                    element["on"+type]=null;
                }
            }
        };

可以用像如下代碼這樣使用以上兩個方法:

    var btn=document.getElementById("myBtn");
        var handler=function(){
            alert("Clicked");
        };
        EventUtil.addHandler(btn,click,handler);
        //其他代碼
        EventUtil.removeHandler(btn,click,handler);

addHandler()和removeHandler()沒有考慮到所有的瀏覽器問題,例如IE中的作用域問題。不過,使用它們添加和移除事件處理程序還是足夠了。此外還要注意,DOM0級對每個事件只支持一個事件處理。好在支持DOM0級的瀏覽器已經不多了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,619評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,155評論 3 425
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,635評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,539評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,255評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,646評論 1 326
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,655評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,838評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,399評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,146評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,338評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,893評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,565評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,983評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,257評論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,059評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,296評論 2 376

推薦閱讀更多精彩內容

  • 1、事件就是用戶或瀏覽器自身執行的某種動作。2、事件處理程序(或事件監聽器)就是響應某個事件的函數。 HTML事件...
    Wonder233閱讀 189評論 0 0
  • 一、事件流 1.1 事件流 事件流:從頁面中接受事件的順序 事件冒泡:即事件開始時由最具體的元素(文檔中嵌套層次最...
    范小飯_閱讀 1,075評論 1 9
  • ** 定義:**事件:用戶或瀏覽器自身執行的某種動作。事件流:描述的是從頁面中接收事件的順序,也可理解為事件在頁面...
    zouyang0921閱讀 591評論 0 0
  • 簡單理解事件是用戶或瀏覽器自身執行的某種動作。諸如click、load而事件處理程序則是響應某個事件的函數。諸如o...
    Miss____Du閱讀 826評論 7 6
  • 今天看了《交辦的藝術》,里面講到將任務交給部下就要全全相信他,不要干涉,這樣才利于進步所要做的就是給他舒適的環境就...
    阿光Jason閱讀 168評論 0 1