面試題-冒泡與捕獲、事件委託、ie事件和dom模型事件、滑鼠事件
一直沒有搞懂jquery中的事件是怎麼新增事件處理程式的。原來就是用了事件委託,關鍵就是通過冒泡方式實現在最高層(document)處理事件,通過判斷事件target的id,給以不同的handler。當然也可以通過事件捕獲來處理,但是因為ie中只有冒泡,所以還是用冒泡相容性更好一些。
細細總結一下:
1.冒泡與捕獲。
冒泡和捕獲是兩個完全不同的事件流傳播方式,當點選頁面上某個元素時,不知道使用者是對該元素感興趣還是對該元素的父元素該興趣?為此提出了兩種不同的事件流模型。一種是捕獲,由網景提出的,首先是最不具體的元素接收到事件,然後再一級一級傳播到最具體的元素。另一種是冒泡,是由ie提出的,它和捕獲完全相反,首先是最具體的元素接收到事件,然後一級一級傳播到最不具體的元素,一般都是document。
2.事件委託
上面的參考博文寫得很清楚了。大概模式就是這樣(以onclick為例子,其他事件mouseover mousemove mouseout mousedown mouseup click dbclick keyup keydown)
document.onclick=function(event){
var event=event?event:window.event;
var target=event.target?event.target:event.srcElement;
switch(target.id){
case:'btnid1':
btnid1handler();
break;
case:'btnid2':
btnid2handler();
break;
}
};
3.ie事件和dom(2)事件模型
ie事件模型的事件流只包括事件冒泡,而dom(2)事件模型的事件流包括三個階段:事件捕獲階段,處於目標階段和事件冒泡階段。ie8以下的版本只支援ie事件模型,ie9及其他瀏覽器都支援dom事件流。
區別:
(1)新增事件處理程式的不同。dom0級只能在冒泡階段呼叫事件處理程式。dom2級事件模型通過addEventListener支援在冒泡和捕獲階段註冊事件處理程式。而ie事件模型通過attachEvent在事件冒泡階段註冊事件處理程式。
(2)事件處理程式的event引數和this的作用域不同。addEventListener中的this就指向當前事件元素,event就是當前事件物件。而attachEvent的this指向window,event是全域性物件作用域window中的event物件,但是同時也會作為引數直接傳遞給事件處理程式函式。但是在只支援ie事件模型的瀏覽器中通過dom0級方法註冊的事件處理程式中的event,只能通過全域性的window.event進行訪問,但無論在哪個瀏覽器中,通過dom0級註冊的事件處理程式中的this也是指向當前事件元素,可以做到很好的跨瀏覽器相容。
(3) 移除事件監聽。通過dom0級註冊的事件處理程式,通過 element.onclick=null;這樣的形式來移除註冊事件。通過dom2級事件註冊的時間處理程式通過removeEventListener來移除事件處理程式,而ie事件模型通過datachEvent來移除。
(4)阻止預設事件模型和阻止事件冒泡的方法。dom2級可以通過preventDefault來阻止事件的預設行為。ie通過returnValue屬性為false來阻止事件的預設行為。dom2採用stopPropagation方法來阻止冒泡,而ie通過cancelBubble屬性為true來阻止冒泡。
4 滑鼠事件
A表示B元素的外部,B表示元素,C表示B的子元素
滑鼠事件有以下幾種:
mouseover:從A到B時觸發,冒泡
mouseenter:從A到B時觸發,並且不冒泡,DOM3級出現的事件
mouseleave:從B到A時觸發,並且不冒泡,DOM3級出現的事件
mouseout:從B到A,或者從C到B時觸發,冒泡
mousemove:B到B時觸發
mousedown:按下任意滑鼠按鈕時觸發
mouseup:釋放滑鼠按鈕時觸發
click:在同一個元素相繼觸發mousedown和mouseup才會觸發click事件,任意一個被取消,都不會觸發click
dbclick:連續兩次click才能觸發dbclick。