1. 程式人生 > >js事件繫結、事件監聽、事件委託

js事件繫結、事件監聽、事件委託

一、JavaScript事件:事件是文件或瀏覽器中發生的特定互動瞬間!
事件流:
1、事件冒泡:事件冒泡即事件最開始由最具體的元素(文件中巢狀層次最深的那個節點)接收,然後逐級向上傳播至最不具體的節點(文件)。
text–>div–>body–>document–>window
2、事件捕獲:事件捕獲即事件最早由不太具體的節點接收,而最具體的節點最後接收到事件。
window–>document–>body–>div–>text

二、Javascript事件處理程式的3種方式

1.在DOM元素中直接繫結;
2.在JavaScript程式碼中繫結;
3.繫結事件監聽函式。

1、HTML事件處理程式:直接在HTML程式碼中新增事件處理程式

<input id="btn" value="按鈕" type="button" onclick="showmsg();">
  <script>
   function showmsg(){
   alert("HTML新增事件處理");
   }
  </script> 

2、DOM0級事件處理程式:指定物件新增事件處理

<input id="btn" value="按鈕" type="button">
  <script>
    var btn= document.getElementById("btn"
);    btn.onclick=function(){       alert("DOM級新增事件處理");     }     btn.onclick=null;//如果想要刪除btn的點選事件,將其置為null即可   
</script>

3、DOM2級事件處理程式
DOM2也是對特定的物件新增事件處理程式,但是主要涉及到兩個方法,用於處理指定和刪除事件處理程式的操作:addEventListener(), attachEvent()和 removeEventListener()。它們都接收三個引數:要處理的事件名、作為事件處理程式的函式和一個布林值(true,捕獲。false,冒泡。預設false。),看下面的一段程式碼:

<input id="btn" value="按鈕" type="button">
  <script>
   var btn=document.getElementById("btn");
   btn.addEventListener("click",showmsg,false);//這裡我們把最後一個值置為false,即不在捕獲階段處理,一般來說冒泡處
理在各瀏覽器中相容性較好
   function showmsg(){
   alert("DOM級新增事件處理程式");
   }
   btn.removeEventListener("click",showmsg,false);//如果想要把這個事件刪除,只需要傳入同樣的引數即可
  </script>

DOM2級事件規定事件包括三個階段:

1、事件捕獲階段;
2、處於目標階段;
3、事件冒泡階段。

補充
IE事件處理程式也對應有兩個方法:attachEvent()新增事件,detachEvent()刪除事件,這兩個方法接收相同的兩個引數:事件處理程式名稱與事處理函式。這裡為什麼沒有布林值呢?因為ie8以及更早的版本只支援事件冒泡,所以最後一個引數預設的相當於false來處理!(支援IE事件處理程式的瀏覽器有IE,opera)。

三、事件委託

事件委託就是利用冒泡的原理,把事件加到父元素或祖先元素上,觸發執行效果。
事件委託優點
1、提高JavaScript效能。事件委託可以顯著的提高事件的處理速度,減少記憶體的佔用。
傳統寫法

<ul id="list">
 <li id="item1" >item1</li>
 <li id="item2" >item2</li>
 <li id="item3" >item3</li>
</ul>

<script>
var item1 = document.getElementById("item1");
var item2 = document.getElementById("item2");
var item3 = document.getElementById("item3");

item1.onclick = function(){
 alert("hello item1");
}
item2.onclick = function(){
 alert("hello item2");
}
item3.onclick = function(){
 alert("hello item3");
}
</script>

事件委託

<ul id="list">
 <li id="item1" >item1</li>
 <li id="item2" >item2</li>
 <li id="item3" >item3</li>
</ul>

<script>
var item1 = document.getElementById("item1");
var item2 = document.getElementById("item2");
var item3 = document.getElementById("item3");

document.addEventListener("click",function(event){
 var target = event.target;
 if(target == item1){
 alert("hello item1");
 }else if(target == item2){
 alert("hello item2");
 }else if(target == item3){
 alert("hello item3");
 }
})
</script>

2、動態的新增DOM元素,不需要因為元素的改動而修改事件繫結。

傳統寫法

<ul id="list">
 <li id="item1" >item1</li>
 <li id="item2" >item2</li>
 <li id="item3" >item3</li>
</ul>

<script>
var list = document.getElementById("list");

var item = list.getElementsByTagName("li");
for(var i=0;i<item.length;i++){
 (function(i){
 item[i].onclick = function(){
 alert(item[i].innerHTML);
 }
 })(i)
}

var node=document.createElement("li");
var textnode=document.createTextNode("item4");
node.appendChild(textnode);
list.appendChild(node);

</script>

點選item1到item3都有事件響應,但是點選item4時,沒有事件響應。說明傳統的事件繫結無法對動態新增的元素而動態的新增事件。

事件委託

<ul id="list">
 <li id="item1" >item1</li>
 <li id="item2" >item2</li>
 <li id="item3" >item3</li>
</ul>

<script>
var list = document.getElementById("list");

document.addEventListener("click",function(event){
 var target = event.target;
 if(target.nodeName == "LI"){
 alert(target.innerHTML);
 }
})

var node=document.createElement("li");
var textnode=document.createTextNode("item4");
node.appendChild(textnode);
list.appendChild(node);

</script>

當點選item4時,item4有事件響應。說明事件委託可以為新新增的DOM元素動態的新增事件。