js 事件冒泡與事件捕獲
一、事件冒泡
事件冒泡是指在事件發生過程中先從目標節點開始執行,並一層一層的相父節點依次查詢直到document,並執行相同事件的過程。
btn1.addEventListener(‘click‘,function(e){
//true 為事件捕獲,false 為事件冒泡
//false為默認方式,冒泡方式執行
//點擊btn1時,如果是事件冒泡,則先執行btn1上的click事件,然後執行父元素div1上的click事件
//如果是事件捕獲,則先執行父元素上的click事件,然後執行btn1上的click事件
var e= e||window.event;
alert( ‘你點擊了btn1‘);
},false);
div1.addEventListener(‘click‘,function(e){
alert(‘你點擊了div1‘);
},false);
這樣的寫法,當你點擊btn1的時候,先彈出“你點擊了btn1”,然後彈出“你點擊了div1”;
二、事件捕獲
事件捕獲就是在事件發生過程中,先從document開始執行相同的事件,依次一層一層查找到目標節點,然後執行相同的事件。
btn1.addEventListener(‘click‘,function(e){
//true 為事件捕獲,false 為事件冒泡
// false為默認方式,冒泡方式執行
//點擊btn1時,如果是事件冒泡,則先執行btn1上的click事件,然後執行父元素上的click事件
//如果是事件捕獲,則先執行父元素上的click事件,然後執行btn1上的click事件
var e= e||window.event;
alert(‘你點擊了btn1‘);
},true);
div1.addEventListener(‘click‘,function(e){
alert(‘你點擊了div1‘);
},true);
這樣的寫法,當你點擊btn1的時候,先彈出“你點擊了div1”,然後彈出“你點擊了btn1”;
三、阻止事件冒泡和事件捕獲
在阻止事件冒泡和捕獲方式上,IE和其他瀏覽器不同;
首先是event的不同;
Event 對象代表事件的狀態,比如事件在其中發生的元素、鍵盤按鍵的狀態、鼠標的位置、鼠標按鈕的狀態。
事件通常與函數結合使用,函數不會在事件發生前被執行!
在IE中輸出的event 為 event;event在IE中為全局函數,可以在任何地方調用。
在FF中輸出的為event; 在FF中只能在實踐中調用,把event作為參數傳進函數內
其他瀏覽器 則為二者都可以;
所以在確定event的時候需要進行瀏覽器兼容
var e = event||window.event;
等同於 e = e?event:window.event;
通過這種方法,IE識別event,其他瀏覽器識別window.event;
在阻止事件方法上也有不同
IE:e.cancelBubble = true; 通過把e.cancelBubble設置為true,來阻止事件分發;
標準瀏覽器:e.stopPropagation(); 標準瀏覽器的stopPropagation 方法可以設置不再派發事件。
兼容代碼如下:
var e = event||window.event;
if(e.stopPropagation){
e.stopPropagation();//標準瀏覽器
}else{
e.cancelBubble = true;//IE瀏覽器
}
四、事件委托方法依托事件冒泡機制
傳統事件綁定
我們給每一個li綁定點擊之後背景顏色變紅的事件;
var uli = document.getElementById(‘uli‘);
var lis = uli.getElementsByTagName(‘li‘);
for (var i = 0;i<lis.length;i++){
lis[i].onclick = function(){
this.style.backgroundColor = ‘red‘;
}
}
//這樣我們就可以做到li上面添加鼠標事件。
//但是如果說我們可能有很多個li用for循環的話就比較影響性能。
一個事件委托實例
html不變,只更改事件綁定的方法
var uli = document.getElementById(‘uli‘);
uli.addEventListener(‘click‘,function(event){
var e = event||window.event;
var target = e.target||e.srcElement;//該方法用於查詢發生event事件的具體節點。
//e.target 是標準瀏覽器的方法
//e.srcElement 是IE中的方法
if (target.nodeName.toUpperCase()==‘LI‘){
target.style.backgroundColor = ‘red‘;
}
});
標準瀏覽器查詢event節點的方法是:window.event.target;
IE瀏覽器查詢event節點的方法是:event.srcElement;
這樣的寫法可以在點擊li的時候向上冒泡至ul,然後執行ul上的綁定事件,這樣就不用給每個li都綁定一個點擊事件.
而且新添加的li元素也可以綁定這樣的事件,不用重新綁定
可以用removeElementListener 來取消綁定的事件函數
五、綁定事件監聽方法
傳統綁定事件
on + click、mouseover、keyup 等
傳統綁定的
優點
- 非常簡單和穩定,可以確保它在你使用的不同瀏覽器中運作一致
- 處理事件時,this關鍵字引用的是當前元素,這很有幫助
缺點
綁定同樣事件的多個函數會覆蓋,只能觸發最後一種。
uli.onclick = function(){
alert(‘1‘);
}
uli.onclick = function(){
alert(‘2‘);
}
這樣的寫法執行時只能執行alert(‘2‘); 解除綁定用 uli.onclick = null;
W3C綁定事件
uli.addEventListener(‘click‘,function(){.........},false);
- W3C綁定的優點
- 該方法同時支持事件處理的捕獲和冒泡階段。事件階段取決於addEventListener最後的參數設置:false (冒泡) 或 true (捕獲)。
- 在事件處理函數內部,this關鍵字引用當前元素。
- 事件對象總是可以通過處理函數的第一個參數(e)捕獲。
- 可以為同一個元素綁定你所希望的多個事件,同時並不會覆蓋先前綁定的事件
- W3C綁定的缺點
- IE不支持,你必須使用IE的attachEvent函數替代。
解除綁定用 removeEventListener(‘click‘,fucntion(){.........});
IE綁定事件
IE用attachEvent方法綁定事件
element.attachEvent(‘onclick‘, function(){
// ...
});
- IE方式的優點
- 可以為同一個元素綁定你所希望的多個事件,同時並不會覆蓋先前綁定的事件。
- IE方式的缺點
- IE僅支持事件捕獲的冒泡階段
- 事件監聽函數內的this關鍵字指向了window對象,而不是當前元素(IE的一個巨大缺點)
- 事件對象僅存在與window.event參數中
- 事件必須以ontype的形式命名,比如,onclick而非click
- 僅IE可用。你必須在非IE瀏覽器中使用W3C的addEventListene
解除綁定函數用 detachEvent(‘onclick‘,fucntion(){})
js 事件冒泡與事件捕獲