事件中的幾種實現方式javascript
Dom0時代 html
一、直接在html的屬性中寫JS代碼java
1 <div onclick="alert(4);">Div1 Element</div>
二、定義一個函數,賦值給html元素的onXXX屬性node
1 <div onclick="clk()">Div Element</div> 2 <script type="text/javascript"> 3 function clk(){ 4 //.... 5 } 6 </script>
三、使用element.onXXX方式瀏覽器
1 <div id="d3">Div Element</div> 2 <script type="text/javascript"> 3 var d3 = document.getElementById('d3'); 4 d3.onclick = function(){ 5 //... 6 } 7 </script>
Dom2時代app
四、添加事件方式,使用addEventListener或IE專有的attachEvent函數
事件流 測試
官方的定義:事件按照從最特定的事件目標到最不特定的事件目標(document對象或者body)的順序觸發。this
也可說,從頁面中接收事件的順序。也就是說當一個事件產生時,這個事件的傳播過程,就是事件流。spa
事件不是單一的,好比:點擊某個按鈕,其實也點擊了包含按鈕的DIV、文檔bod、document.
1 <body onclick="alert(3)"> 2 <div onclick="alert(2)"> 3 <button onclick="alert(1)">測試按鈕</button> 4 </div> 5 </body>
在IE中,冒泡,會按這個順序輸出:1,2,3;
但在Netscape Navigator 4.0中則是‘反的’,它所支持的是捕獲:輸出3,2,1;
而DOM標準中事件流將這兩種方式結合
window -> document -> body -> div -> button -> button -> div -> body -> document -> window;
這某些狀況下,咱們可能就須要去阻止事件流的傳播:
1 function stopEvent (evt) { 2 var e = (evt != null) ? evt : window.event; 3 if (window.event) { 4 e.cancelBubble=true; // ie 5 } else { 6 e.stopPropagation(); // 標準組織 7 } 8 }
綁定、解綁、參數、事件對象在IE與W3C中的區別
1 Evt.extend({ 2 // 添加事件 3 on : function(ele,type, fn){ 4 if(document.addEventListener){ 5 ele.addEventListener(type, fn, false); 6 }else if(document.attachEvent){ 7 ele.attachEvent('on' + type, fn); 8 }else{ 9 ele['on' + type] = fn; 10 } 11 }, 12 // 解除事件 13 un : function(ele,type, fn){ 14 if(document.removeEventListener){ 15 ele.removeEventListener(type, fn); 16 }else if(document.detachEvent){ 17 ele.detachEvent(type, fn); 18 }else{ 19 ele['on' + type] = null; 20 } 21 }, 22 /*點擊*/ 23 click : function(ele,fn){ 24 this.on(ele,'click',fn); 25 }, 26 // ... 27 });
Event接口(IE低版本瀏覽器不作專門的討論)
JS裏並無嚴格的接口概念,只是爲程序提供了某個對象擁有某些屬性或者方法的描述
Event對象實現Event接口或子接口,聲明瞭該種事件類型的詳細信息。
其中Event是基礎接口,UIEvent 和 MutationEvent是他的子接口。而MouseEvent又是UIEvent的子接口
Event 接口具備以下屬性和方法:
Type 指明事件的類型
Target 發生事件的節點 // srcElement
currentTarget 事件當前傳播到達的節點。
eventPhase 當前所處的事件傳播階段(捕獲、目標、冒泡)
timeStamp 事件發生的時間點(時間戳)
cancelable 聲明事件是否取消默認動做
bubbles 聲明事件時候在文檔中起泡
stopPorpagation() 阻止冒泡 // cancelBubble
preventDefault 阻止默認動做的執行
...
UIEvent接口屬性
Event的子接口,在其基礎上定義了兩個新的屬性:
view 發生事件的window對象
detail 提供事件的額外信息
MouseEvent 接口屬性
是UIEvent的子接口,在UIEvent基礎上定義了下列屬性
button mousedown click 等事件中,鼠標鍵的狀態(0鼠標左鍵2鼠標右鍵)
altKey ctrlKey metaKay shiftKey 在鼠標事件發生時。是否按下了該鍵
clientX \Y 事件發生時,鼠標指針相對於瀏覽器左上角的座標
screenX\Y 相對於顯示器左上角的座標
...
事件的代理與委託
經過事件的冒泡機制來實現的
優勢:
1、是能夠節省大量的內存佔用,減小事件註冊,好比在table上能夠代理全部td的click事件
2、對新增的子對象不須要再次綁定事件,適於動態內容部分
缺點:
不能全部的事件都用代理,不該該觸發的元素也被綁上了事件。
1 function delegate(pid, eventType, selector, fn) { 2 var parent = $$.$id(pid); 3 function handle(e){ 4 var target = $$.GetTarget(e); 5 console.log(target.nodeName) 6 if(target.nodeName.toLowerCase()=== selector || target.id === selector || target.className.indexOf(selector) != -1){ 7 fn.call(target); 8 } 9 } 10 parent[eventType]=handle; 11 } 12 delegate('table','onclick','td',function(){ 13 this.style.color='white' 14 this.style.background='red' 15 })
自定義事件
1 //將有參數的函數封裝爲無參數的函數 2 function createFunction(obj, strFunc) { 3 var args = []; //定義args 用於存儲傳遞給事件處理程序的參數 4 if (!obj) obj = window; //若是是全局函數則obj=window; 5 //獲得傳遞給事件處理程序的參數 6 for (var i = 2; i < arguments.length; i++){ 7 // alert(arguments[i]); 8 args.push(arguments[i]); 9 } 10 //用無參數函數封裝事件處理程序的調用 11 return function() { 12 obj[strFunc].apply(obj, args); //將參數傳遞給指定的事件處理程序 13 } 14 } 15 function class1() { 16 } 17 class1.prototype = { 18 show: function() { 19 this.onShow(); 20 }, 21 onShow: function() { } 22 } 23 function objOnShow(userName) { 24 alert("hello," + userName); 25 } 26 function test() { 27 var obj = new class1(); 28 var userName = "test"; 29 obj.onShow = createFunction(null, "objOnShow", userName); 30 console.log(obj.onShow) 31 obj.show(); 32 } 33 test()