js 自定義事件 包含 添加、激活、銷毀


1.思路

(1)構思

var eventTarget = {
  addEvent: function(){
    //添加事件
  },
  fireEvent: function(){
    //觸發事件
  },
  removeEvent: function(){
    //移除事件
  }
};

(2)建立一一對應的映射表

var eventTarget = {
  //保存映射
  handlers:{},
  addEvent: function(){
    //處理代碼
  },
  fireEvent: function(){
    //觸發代碼
  },
  removeEvent: function(){
    //移出代碼
  }
};

(3)構建映射關系

handlers = {
  "type1":[
    "fun1",
    "fun2",
    // "..."
  ],
  "type2":[
    "fun1",
    "fun2"
    // "..."
  ]
  //"..."
}

這樣每一個類型可以有多個處理函數,以便於我們以后擴充 

(4)構建后

//直接量處理js自定義事件
var eventTarget = {
  //保存事件類型,處理函數數組映射
  handlers:{},
  //注冊給定類型的事件處理程序,
  //type -> 自定義事件類型, handler -> 自定義事件回調函數
  addEvent: function(type, handler){
    //判斷事件處理數組是否有該類型事件
    if(eventTarget.handlers[type] == undefined){
      eventTarget.handlers[type] = [];
    }
    //將處理事件push到事件處理數組里面
    eventTarget.handlers[type].push(handler);
  },
  //觸發一個事件
  //event -> 為一個js對象,屬性中至少包含type屬性,
  //因為類型是必須的,其次可以傳一些處理函數需要的其他變量參數。(這也是為什么要傳js對象的原因)
  fireEvent: function(event){
    //判斷是否存在該事件類型
    if(eventTarget.handlers[event.type] instanceof Array){
      var _handler = eventTarget.handlers[event.type];
      //在同一個事件類型下的可能存在多種處理事件,找出本次需要處理的事件
      for(var i = 0; i < _handler.length; i++){
        //執行觸發
        _handler[i](event);
      }
    }
  },
  //注銷事件
  //type -> 自定義事件類型, handler -> 自定義事件回調函數
  removeEvent: function(type, handler){
    if(eventTarget.handlers[type] instanceof Array){
      var _handler = eventTarget.handlers[type];
      //在同一個事件類型下的可能存在多種處理事件,找出本次需要處理的事件
      for(var i = 0; i < _handler.length; i++){
        //找出本次需要處理的事件下標
        if(_handler[i] == handler){
          break;
        }
      }
      //刪除處理事件
      _handler.splice(i, 1);
    }
  }
};

這是一種調用運行的方法

eventTarget.addEvent("eat",function(){
  console.log(123);  //123
});
eventTarget.fireEvent({type: "eat"});

這種方法有一個缺點,不能刪除該處理事件,因為我們是用映射表做的,而且也不提倡,直接給映射表里面存這么多數據,有點多。

另一種方法,將處理事件提取出來(推薦)

function b(){
   console.log(123);
}
eventTarget.addEvent("eat",b);
eventTarget.fireEvent({
  type: "eat"
});                   //123
eventTarget.removeEvent("eat",b);
eventTarget.fireEvent({type: "eat"});  //空

也可以這樣,傳遞更多的參數

eventTarget.fireEvent({
  type: "eat",
  food: "banana"
}); 
function b(data){
   console.log(data.food); //banana
}

(5)總結

//自定義事件構造函數
function EventTarget(){
  //事件處理程序數組集合
  this.handlers = {};
}
//自定義事件的原型對象
EventTarget.prototype = {
  //設置原型構造函數鏈
  constructor: EventTarget,
  //注冊給定類型的事件處理程序,
  //type -> 自定義事件類型, handler -> 自定義事件回調函數
  addEvent: function(type, handler){
    //判斷事件處理數組是否有該類型事件
    if(typeof this.handlers[type] == 'undefined'){
      this.handlers[type] = [];
    }
    //將處理事件push到事件處理數組里面
    this.handlers[type].push(handler);
  },
  //觸發一個事件
  //event -> 為一個js對象,屬性中至少包含type屬性,
  //因為類型是必須的,其次可以傳一些處理函數需要的其他變量參數。(這也是為什么要傳js對象的原因)
  fireEvent: function(event){
    //模擬真實事件的event
    if(!event.target){
      event.target = this;
    }
    //判斷是否存在該事件類型
    if(this.handlers[event.type] instanceof Array){
      var handlers = this.handlers[event.type];
      //在同一個事件類型下的可能存在多種處理事件,找出本次需要處理的事件
      for(var i = 0; i < handlers.length; i++){
        //執行觸發
        handlers[i](event);
      }
    }
  },
  //注銷事件
  //type -> 自定義事件類型, handler -> 自定義事件回調函數
  removeEvent: function(type, handler){
    //判斷是否存在該事件類型
    if(this.handlers[type] instanceof Array){
      var handlers = this.handlers[type];
      //在同一個事件類型下的可能存在多種處理事件
      for(var i = 0; i < handlers.length; i++){
        //找出本次需要處理的事件下標
        if(handlers[i] == handler){
          break;
        }
      }
      //從事件處理數組里面刪除
      handlers.splice(i, 1);
    }
  }
};

// 調用方法

function b(){
  console.log(123);
}
 
var target = new EventTarget();
target.addEvent("eat", b);
 
target.fireEvent({
  type: "eat"
});                 //123

.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM