自定義事件,就是本身定義事件類型,本身定義事件處理函數。數組
咱們平時操做dom時常常會用到onclick、onmousemove等瀏覽器特定行爲的事件類型。瀏覽器
封裝is自定義事件基本的構思:dom
var eventTarget = { addEvent: function(){ //添加事件 }, fireEvent: function(){ //觸發事件 }, removeEvent: function(){ //移除事件 } };
在js默認事件中事件類型以及對應的執行函數是一一對應的,可是自定義事件,須要一個映射表來創建二者之間的聯繫。函數
如: 這樣每一個類型能夠處理多個事件函數this
handlers = { "type1":[ "fun1", "fun2", // "..." ], "type2":[ "fun1", "fun2" // "..." ] //"..." }
代碼實現:spa
function EventTarget(){ //事件處理程序數組集合 this.handlers={}; } //自定義事件的原型對象 EventTarget.prototype={ //設置原型構造函數鏈 constructor:EventTarget, //註冊給定類型的事件處理程序 //type->自定義事件類型,如click,handler->自定義事件回調函數 addEvent:function(type,handler){ //判斷事件處理函數中是否有該類型事件 if(this.handlers[type]==undefined){ this.handlers[type]=[]; } this.handlers[type].push(handler); }, //觸發事件 //event爲一個js對象,屬性中至少包含type屬性。 fireEvent:function(event){ //模擬真實事件的event if(!event.target){ event.target=this; } //判斷是否存在該事件類型 if(this.handlers[event.type] instanceof Array){ var items=this.handlers[event.type]; //在同一事件類型下可能存在多個事件處理函數,依次觸發 //執行觸發 items.forEach(function(item){ item(event); }) } }, //刪除事件 removeEvent:function(type,handler){ //判斷是否存在該事件類型 if(this.handlers[type] instanceof Array){ var items=this.handlers[type]; //在同一事件類型下可能存在多個處理事件 for(var i=0;i<items.length;i++){ if(items[i]==handler){ //從該類型的事件數組中刪除該事件 items.splice(i,1); break; } } } } } //調用方法 function fun(){ console.log('執行該方法'); } function fun1(obj){ console.log('run '+obj.min+'s'); } var target=new EventTarget(); target.addEvent("run",fun);//添加事件 target.addEvent("run",fun1);//添加事件 target.fireEvent({type:"run",min:"30"});//執行該方法 123 target.removeEvent("run",fun);//移除事件 target.fireEvent({type:"run",min:"20"});//123
爲何要把方法添加到對象原型上?prototype
在構造函數中加屬性,在原型中加方法。code
將屬性和方法都寫在構造函數裏是沒有問題的,可是每次進行實例化的過程當中,要重複建立功能不變的方法。對象
因爲方法本質上是函數,其實也就是在堆內存中又新建了一個對象空間存放存儲函數,形成了沒必要要的資源浪費。blog
在自己添加會致使每次對象實例化時代碼被複制,都須要申請一塊內存存放該方法。