一、事件流
1、事件冒泡
事件沿DOM樹向上傳播
2、事件捕獲
事件到達預定目標之前被捕獲
3、DMO2級事件
事件捕獲階段,處於目標階段,事件冒泡階段
二、事件處理常式
格式:on + "事件名"
1、HTML事件處理常式
1 <input type="button" value="click me" onclick="showMessage()" >
2、DOM0級事件處理常式
1 element.onclick = function(){ //... }
3、DOM2級事件處理常式
1 element.addEventListener(type,handle,boolean);2 element.removeEventListener(type,handle,boolean);
4、IE事件處理常式(ie9以下版本)
1 element.attachEvent("on" + type,handle);2 element.detachEvent("on" + type,handle);
【註:此時事件處理函數的範圍為全域範圍,this等於window】
三、事件對象
1、DOM(DOM0或DOM2級)中的事件對象
a、事件對象(event)作為參數傳入於事件處理常式中
b、對象this,currentTarget,target之間的關係
對象this始終等於currentTarget
當事件處於捕獲或冒泡階段時,三者不相等
當事件處於目標階段時,三者相等
c、preventDefault()與stopPropagation()
preventDefault(): 取消事件預設行為
stopPropagation(): 阻止事件的捕獲和冒泡
2、IE中的事件對象(ie9以下版本)
a、通過window.event來訪問事件對象,在使用attach添加事件時,也可以作為參數傳入
b、cancelBubble設定為true時,取消事件冒泡
c、returnValue設定為false時,取消事件的預設行為
d、srcElement與DOM中的target屬性相同
四、跨瀏覽器的事件對象
1 var EventUtil = { 2 addHandler: function(element,type,handler){ 3 if(element.addEventListener){ 4 element.addEventListener(type,handler,false); 5 }else if(element.attachEvent){ 6 element.attachEvent( "on" + type,handler); 7 }else{ 8 element["on" + type] = handler; 9 }10 },11 getEvent: function(e){12 return e ? e : window.event;13 },14 getTarget: function(e){15 e = this.getEvent(e);16 return e.target || e.srcElement;17 },18 getRelatedTarget: function(e){19 e = this.getEvent(e);20 if(e.relatedTarget){21 return e.relatedTarget; 22 }else if(e.fromTarget){23 return e.fromTarget; 24 }else if(e.toTarget){25 return e.toTarget;26 }else{27 return null;28 }29 },30 stopPropagation: function(e){31 e = this.getEvent(e);32 if(e.stopPropagation){33 e.stopPropagation();34 }else{35 e.cancelBubble = true;36 }37 },38 preventDefault: function(e){39 e = this.getEvent(e);40 if(e.preventDefault){41 e.preventDefault();42 }else{43 e.returnValue = false;44 }45 },46 removeHandler: function(element,type,handler){47 if(element.removeEventListener){48 element.removeEventListener(type,handler,false);49 }else if(element.detachEvent){50 element.detachEvent( "on" + type,handler);51 }else{52 element["on" + type] = null;53 }54 }55 }
五、事件委託
事件委託: 就是利用事件冒泡,把事件註冊到目標元素的更高層級元素上,用來減少頁面事件處理常式,提高頁面效能
如:HTML
1 <ul id="ul">2 <li id="li1"></li>3 <li id="li2"></li>4 <li id="li3"></li>5 </ul>
JavaScript
1 var ul = document.getElementById("ul"); 2 EventUtil.addHandler(ul,"click",function(e){ 3 var target = EventUtil.getTarget(e); 4 switch(target.id){ 5 case "li1": 6 console.log(target.id); 7 break; 8 9 case "li2":10 console.log(target.id);11 break;12 13 case "li3":14 console.log(target.id);15 break;16 }17 });
六、命名空間(對象)中的變數訪問
命名空間中的變數可以直接存取全域中的變數,但是不能訪問其他(函數)範圍中的變數,只能通過傳遞參數來訪問
1、錯誤碼:
1 obj = {2 method: function(){3 console.log(arg);4 }5 }6 function fn(arg){7 obj.method();8 }9 fn("test"); //arg is not defined
不能直接存取其他範圍中的變數
2、訪問全域變數:
1 var arg = "test";2 var obj = {3 method: function(){4 console.log(arg); //可以直接存取全域變數arg5 }6 }7 obj.method(); //test
3、傳遞參數來訪問變數:
1 var obj = {2 method: function(arg){ //通過傳遞參數來訪問其他函數中的變數3 console.log(arg);4 }5 }6 function fn(arg){7 obj.method(arg);8 }9 fn("test"); //test