国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

詳解javascript實現自定義事件

2019-11-20 10:45:47
字體:
來源:轉載
供稿:網友

我們平時在操作dom時候經常會用到onclick,onmouseover等一系列瀏覽器特定行為的事件,
那么自定義事件,顧名思義,就是自己定義事件類型,自己定義事件處理函數,在合適的時候需要哪個事件類型,就去調用哪個處理程序

1.js所支持的瀏覽器默認事件

瀏覽器特定行為的事件,或者叫系統事件,js默認事件等等都行,大家知道我指的什么就行,下文我叫他js默認事件。
js默認事件的事件綁定,事件移出等一系列操作,相信大家都有用到過,如:

//DOM0級事件處理程序var oDiv = document.getElementById('oDiv');oDiv.onclick = function(){  alert("你點擊了我");}

又或者

//DOM2級事件處理程序var oDiv = document.getElementById('oDiv');//非ieoDiv.addEventListener("click",function(){  alert("你點擊了我");},false); //ieoDiv.attachEvent("onclick", function(){  alert("你點擊了我");});

所有我就不做過多的研究,畢竟我們來討論js自定義事件,這里給出一個我之前封裝過的處理js默認事件的代碼:

//跨瀏覽器的事件處理程序 //調用時候直接用domEvent.addEvent( , , );直接調用 //使用時候,先用addEvent添加事件,然后在handleFun里面直接寫其他函數方法,如getEvent; //addEventListener和attachEvent---都是dom2級事件處理程序 var domEvent = {   //element:dom對象,event:待處理的事件,handleFun:處理函數   //事件名稱,不含“on”,比如“click”、“mouseover”、“keydown”等   addEvent:function(element,event,handleFun){     //addEventListener----應用于mozilla     if(element.addEventListener){       element.addEventListener(event,handleFun,false);     }//attachEvent----應用于IE     else if(element.attachEvent){       element.attachEvent("on"+event,handleFun);     }//其他的選擇dom0級事件處理程序     else{       //element.onclick===element["on"+event];       element["on"+event] = handleFun;     }   },   //事件名稱,含“on”,比如“onclick”、“onmouseover”、“onkeydown”等   removeEvent:function(element,event,handleFun){     //removeEventListener----應用于mozilla     if (element.removeEventListener) {       element.removeEventListener(event,handleFun,false);     }//detachEvent----應用于IE     else if (element.detachEvent) {       element.detachEvent("on"+event,handleFun);     }//其他的選擇dom0級事件處理程序     else {       element["on"+event] = null;     }   },   //阻止事件冒泡   stopPropagation:function(event){     if(event.stopPropagation){       event.stopPropagation();     }else{       event.cancelBubble = true;//IE阻止事件冒泡,true代表阻止     }   },   //阻止事件默認行為   preventDefault:function(event){     if(event.preventDefault){       event.preventDefault();     }else{       event.returnValue = false;//IE阻止事件冒泡,false代表阻止     }   },   //獲得事件元素   //event.target--非IE   //event.srcElement--IE   getElement:function(event){     return event.target || event.srcElement;   },   //獲得事件   getEvent:function(event){     return event? event : window.event;   },   //獲得事件類型   getType:function(event){     return event.type;   } }; 

接下類我們不如正題,js自定義事件

2.對象直接量封裝js自定義事件

根據上面的封裝,我們可以這樣構思

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

相信這樣大家還是比較好理解的,然后又有一個問題大家可以想到,那就是,js默認事件,js可以一一對應,知道那個是那個,那么我們的自定義事件呢,這個一一對應的映射表只能我們自己去建立,然后我這樣

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

我是這樣構建這個映射關系的

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

這樣每一個類型可以有多個處理函數,以便于我們以后擴充
接下來就是代碼方面的實戰的,編寫具體的處理代碼了…

相信大家對于這個思路已經很清楚了,我直接附上代碼

//直接量處理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"});                   //123eventTarget.removeEvent("eat",b);eventTarget.fireEvent({type: "eat"});  //空

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

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

總結:字面量這種方法,有點兒缺點,就是萬一一不小心,把某個屬性在handler函數里面,賦值null,這樣會造成我們的的eventTarget 方法崩盤。看來原型應該是個好方法,更安全一點。

3.對象原型封裝js自定義事件

由于前面思路基本都講清楚了,這里我直接附上代碼,大家可以研究下其中的利弊,或許你可以找到更好的方法解決Ta…

//自定義事件構造函數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

原型這種方法,與直接量方法功能是一樣的…

以上就是本文的全部內容,希望對大家的學習有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 荥经县| 莫力| 拉孜县| 麦盖提县| 鞍山市| 淅川县| 长垣县| 泸州市| 嵊州市| 德令哈市| 鹤山市| 武邑县| 南溪县| 鲁山县| 河西区| 象山县| 天峨县| 峨边| 星子县| 德格县| 白水县| 香河县| 上虞市| 上蔡县| 罗山县| 烟台市| 东宁县| 游戏| 迭部县| 仁化县| 马鞍山市| 凉城县| 华宁县| 黑山县| 崇明县| 汶川县| 浦县| 灵山县| 金山区| 皮山县| 神木县|