13.1 事件流
事件流描述的是從頁面中接收事件的順序。
當瀏覽器發展到第四代時,瀏覽器開發團隊遇到了一個很有意思的問題:頁面的哪一部分會擁有某個特定事件?
針對這一個問題,IE提出了事件冒泡,Netscape提出了事件捕獲
13.1.1 事件冒泡
即事件開始時由最具體的元素(文檔中嵌套層次最深的那個節點)接收,然后逐級向上傳播到較為不具體的節點(文檔)。
13.1.2 事件捕獲
即不太具體的節點應該更早接收到事件,而最具體的節點應該最后接收到事件。
由于老版本的瀏覽器不支持,因此很少有人使用事件捕獲。我們也建議大家放心的使用事件冒泡,在有特殊需要時再使用事件捕獲。
13.1.3 DOM事件流
13.2 事件處理程序
響應某個事件的函數叫做事件處理程序,比如onclick
13.2.1 HTML事件處理程序
<input type = 'button' value="Click me" onclick = 'showMsg()' />
function showMsg(){
}
缺點:
(1) 存在時差問題。如果showMsg定位在頁面最底部,用戶在showMsg函數未解析之前點擊按鈕,會發生錯誤。
(2) 不同瀏覽器對其中作用域鏈理解不一樣。
(3) html和js耦合太嚴重。
13.2 DOM0級事件處理程序
var btn = document.getElementById('myBtn');
btn.onclick = function(){
alert(this.id); //myBtn
}
使用DOM0級方法指定的事件處理程序被認為是元素的方法,因此,程序中的this引用當前元素。
13.2.3 DOM2級事件處理程序
即事件監聽。使用addEventListener()和removeEventListener();
13.2.4 IE事件處理程序
事件監聽。attachEvent() 和 detachEvent()
13.3 事件對象
即event,在觸發DOM上的某個事件時,會產生一個事件對象event,這個對象包含著所有與事件有關的信息。
13.3.1 DOM中的事件對象。
在需要通過一個函數處理多個事件時,可以這樣:
var btn = document.getElementById('myBtn');
var handler = function(event){
switch(event.type){
case "click":
alert('Clicked');
break;
case 'mouseover':
alert('mouseover');
break;
case 'mouseout':
alert(mouseout);
break;
}
}
btn.onclick = handler;
btn.onmouseover = handler;
btn.mouseout = mouseout;
阻止默認行為:
event.preventDefault();
阻止冒泡
event.stopPropagation();
event.eventPhase 用來確定事件當前正位于事件流的哪個階段。
1: 捕獲階段
2: 處于目標對象上
3: 冒泡階段
13.4 事件類型
13.4.1 UI事件
指的是那些不一定與用戶操作有關的事件
這些事件都與window對象有關
(1) load事件(圖像,JS,CSS文件等都可以)
在相應對象上監聽load事件即可
(2) unload事件
(3) resize事件
(4) scroll事件
13.4.2 焦點事件
(1) blur 在元素失去焦點時觸發,這個事件不會冒泡。
(2) focus 在元素獲得焦點時觸發,這個事件不會冒泡。
13.4.3 鼠標與滾輪事件
(1) click
(2) dblclick
(3) mousedown 用戶按下任意鼠標按鈕時觸發。不能通過鍵盤觸發。
(4) mouseenter 鼠標光標從元素外部首次移動到元素范圍之內時觸發。這個事件不冒泡,而且在光標移動到后代元素上不會觸發。
(5) mouseleave 在位于元素上方的鼠標光標移動到元素范圍之內時觸發。這個事件不冒泡,而且在光標移動到后代元素上不會觸發。
(6) mousemove 當鼠標指針在元素內部移動時 重復 觸發。
(7) mouseout 在鼠標指針位于一個元素上方,然后用戶將其移入另一個元素時觸發。又移入的另一個元素可能位于前一個元素的外部,
也可能是這個元素的子元素。
(8) mouseover 在鼠標指針位于一個元素外部,然后用戶將其首次移入另一個元素邊界之內時觸發。
(9) mouseup 用戶釋放鼠標按鈕時觸發。
頁面上所有元素都支持鼠標事件。除了mouseenter 和 mouseleave,所有鼠標事件都會冒泡,也可以被取消,而取消鼠標事件將會影響瀏覽器的默認行為。
1. 客戶區坐標位置
以頁面文檔左上角為原點。
clientX:發生事件時鼠標指針在視口中的水平坐標
clientY:發生事件時鼠標指針在視口中的垂直坐標
2. 頁面坐標位置
在頁面沒有滾動情況下,pageX和pageY的值與clientX和clientY的值相等
有滾動情況下:
pageY = 鼠標舉例文檔頂部距離 + 垂直滾動距離
clientY = 鼠標舉例文檔頂部距離
3. 屏幕坐標位置
鼠標事件發生時,不僅會有相對于瀏覽器窗口的位置,還有一個相對于整個電腦屏幕的位置
screenX和screenY
13.4.5 復合事件
13.4.7 HTML5事件
1. contextmenu 用以表示何時應該顯示上下文菜單,以便開發人員取消默認的上下文菜單而提供自定義的菜單。
禁止默認行為,正常瀏覽器:event.preventDefault() IE:event.returnValue = false;
2. beforeunload 事件
3. DOMContentLoaded。在形成完整的DOM樹之后就會觸發,不理會圖像,JS文件,CSS文件或其他資源是否已經下載完畢。
13.5 內存和性能
在js中,添加到頁面上的事件處理程序數量將直接關系到頁面的整體運行性能。事實上,從如何利用好事件處理程序的角度出發,還是有一些方法能夠提升性能的。
13.5.1 事件委托
當頁面上很多元素需要觸發同一事件時,可考慮使用事件委托來提高性能。
<ul id="myLinks">
<li id="doSomeWhere">doSomeWhere</li>
<li id="doSomeThing">doSomeThing</li>
<li id="sayHi">sayHi</li>
</ul>
var list = $('#myLinks')
$(list).on('click', function(e){
var target = $(e.target)[0];
e.stopPropagation();
switch(target.id){
case 'doSomeWhere':
alert('doSomeWhere');
break;
case 'doSomeThing':
alert('doSomeThing');
break;
case 'sayHi':
alert('sayHi');
break;
}
})
13.5.2 移除事件處理程序
解綁事件
13.6 模擬事件
13.6.1 DOM中的事件模擬
小結:
在使用事件時,需要考慮如下一些內存與性能方面的問題: