瞭解javascript中的事件(一)

來源:互聯網
上載者:User

  一、事件概念   什麼是事件?說白了,事件是文檔或瀏覽器中發生的特定互動瞬間!比如滑鼠點擊,滑過等等。 二、事件流   事件流就是描述了頁面中接受事件的順序。在瀏覽器發展的初期,兩大瀏覽器廠商IE和Netscape互掐,出現了一個坑爹的情況,那就是他們對事件流的解釋出現了兩中截然相反的定義。也就是我們所熟悉的:IE的事件冒泡,Netscape的事件捕獲。先來一張圖,簡要的看下結構(以前網上看到的,也不知道出處了,盜用一下,感謝原作者辛勤的visio畫圖,哈哈)   2.1事件冒泡   概念:事件冒泡即事件最開始由最具體的元素(文檔中嵌套層次最深的那個節點)接收,然後逐級向上傳播至最不具體的節點(文檔)。拿上面的圖來說明,就是當點擊text部分時,先由text處的元素接收,然後逐級傳播至window,即執行6-7-8-9-10的過程。 2.2事件捕獲   概念:事件捕獲即事件最早由不太具體的節點接收,而最具體的節點最後接收到事件。同理,在上面的模型中,就是點擊text部分時,先由window接收,然後逐級傳播至text元素,即執行1-2-3-4-5的過程。   具體在代碼中怎樣表現呢,後面會給出代碼的介紹,客官莫急。 三、事件處理常式   產生了事件,我們就要去處理他。事件處理常式主要有三種方式:  3.1 HTML事件處理常式   即我們直接在HTML代碼中添加事件處理常式。來一段代碼吧,寫了這麼久沒有代碼實在是憋得慌,哎,程式員的毛病! 1 <input id="btn1" value="按鈕" type="button" onclick="showmsg();">2 <script>3     function showmsg(){4         alert("HTML添加事件處理");5     }6 </script>  從上面的代碼中我們可以看出,事件處理是直接嵌套在元素裡頭的,這樣有一個毛病:就是html代碼和js的耦合性太強,如果哪一天我想要改變js中showmsg,那麼我不但要再js中修改,我還需要到html中修改,一兩處的修改我們能接受,但是當你的代碼達到萬行層級的時候,修改起來就需要勞民傷財了,所以這個方式我們並不推薦使用。   3.2 DOM0級事件處理常式   即為指定對象添加事件處理。慣例,看下面的一段代碼 複製代碼1 <input id="btn2" value="按鈕" type="button">2 <script>3   var btn2= document.getElementById("btn2");4     btn2.onclick=function(){5     alert("DOM0級添加事件處理");6   }  7   btn.onclick=null;//如果想要刪除btn2的點擊事件,將其置為null即可 8 </script>  複製代碼  從上面的代碼中,我們能看出,相對於HTML事件處理常式,DOM0級事件,html代碼和js代碼的耦合性已經大大降低。但是,聰明的程式員還是不太滿足,期望尋找更簡便的處理方式,下面我們來說第三種處理方法。  3.3 DOM2級事件處理常式   DOM2也是對特定的對象添加事件處理常式,但是主要涉及到兩個方法,用於處理指定和刪除事件處理常式的操作:addEventListener()和 removeEventListener()。   它們都接收三個參數:要處理的事件名、作為事件處理常式的函數和一個布爾值(是否在捕獲階段處理事件)。看下面的一段代碼: 複製代碼1 <input id="btn3" value="按鈕" type="button">2 <script>3     var btn3=document.getElementById("btn3");4     btn3.addEventListener("click",showmsg,false);//這裡我們把最後一個值置為false,即不在捕獲階段處理,一般來說冒泡處理在各瀏覽器中相容性較好5     function showmsg(){6         alert("DOM2級添加事件處理常式");7     }8     btn3.removeEventListener("click",showmsg,false);//如果想要把這個事件刪除,只需要傳入同樣的參數即可9 </script>複製代碼  這裡我們可以看到,在添加刪除事件處理的時候,最後一種方法更直接,也最簡便。但是需要注意的是,在刪除事件處理的時候,傳入的參數一定要跟之前的參數一致,否則刪除會失效!   說到這裡,我們來一點代碼來說明下事件冒泡和事件捕獲的流程,同時也讓大家能看出二者的區別  複製代碼 1 <!doctype html> 2 <html lang="en"> 3 <head> 4     <meta charset="UTF-8"> 5     <title>Document</title> 6     <style> 7         #p{width:400px;height:200px;border:1px solid black;} 8         #c{width:200px;height:100px;border:1px solid red;} 9     </style>10 11 </head>12 <body>13     <div id="p">14         i am parent15         <div id="c">i am children</div>16     </div>17     <script>18      var p = document.getElementById('p');19        var c = document.getElementById('c');20        c.addEventListener('click', function () {21             alert('子節點捕獲')22         }, true);23 24        c.addEventListener('click', function () {25             alert('子節點冒泡')26        }, false);27 28        p.addEventListener('click', function () {29              alert('父節點捕獲')30          }, true);31  32        p.addEventListener('click', function () {33            alert('父節點冒泡')34         }, false);35     </script>36 </body>37 </html>複製代碼運行上面的代碼,點擊子項目的時候,我們會發現,執行的先後順序是:父節點捕獲--子節點捕獲--子節點冒泡--父節點冒泡。從這個例子中,大家也能明白,為什麼說   DOM2級事件規定事件包括三個階段:     1)事件捕獲階段;2)處於目標階段;3)事件冒泡階段   首先是捕獲,然後處於目標階段(即來到事件的發出位置),最後才是冒泡,   嚴重PS:不科學的是,居然木有DOM1級事件處理常式,大家注意下,別鬧出笑話了!   【補充】IE事件處理常式也對應有兩個方法:attachEvent()添加事件,detachEvent()刪除事件,這兩個方法接收相同的兩個參數:事件處理常式名稱與事件處理函數。這裡為什麼沒有布爾值呢?因為ie8以及更早的版本只支援事件冒泡,所以最後一個參數預設的相當於false來處理!(支援IE事件處理常式的瀏覽器有IE,opera) 3.4 事件處理常式的瀏覽器安全色性   既然不同的瀏覽器對事件處理常式有這自己不同的支援,那麼,我們在開發中,豈不是每次使用事件處理常式時都要對不同的瀏覽器做一次相容?這裡我們封裝一個相容方法,以後在事件處理的時候,直接調用即可,看下面一段代碼: 複製代碼 1 <!doctype html> 2 <html lang="en"> 3 <head> 4     <meta charset="UTF-8"> 5     <title>Document</title> 6 </head> 7 <body> 8 <input id="btn" type="button" value="按鈕"> 9     <script>10     var eventHandler={11         addHandler:function(element,type,func){12             if(element.addEventListener){13                 element.addEventListener(type,func,false);14             }else if(element.detachEvent){15                 element.attachEvent('on'+type,func);16             }else{17                 element['on'+type]=func;18             }19         },20         removerHandler:function(element,type,func){21             if(element.removeEventListener){22                 element.removeEventListener(type,func,false);23             }else if(element.detachEvent){24                 element.detachEvent('on'+type,func);25             }else{26                 element['on'+type]=null;27             }28         }29     }30     function showmsg(){31         alert("hello");32     }33     var btn=document.getElementById("btn");34     eventHandler.addHandler(btn,"click",showmsg);35     //eventHandler.removerHandler(btn,"click",showmsg);//去掉事件處理36     </script>37 </body>38 </html>複製代碼  上面的代碼在ie和其他瀏覽器中都能正常處理事件,以後如果需要使用相容性的操作,都可以直接調用這段代碼。  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.