最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解javascript實(shí)現(xiàn)自定義事件

 更新時(shí)間:2016年01月19日 16:13:58   作者:xi_2130  
這篇文章主要為大家介紹了javascript實(shí)現(xiàn)自定義事件的方法,自定義事件,顧名思義,就是自己定義事件類型,自己定義事件處理函數(shù),javascript如何實(shí)現(xiàn)自定義事件,需要了解的朋友可以參考下

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

1.js所支持的瀏覽器默認(rèn)事件

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

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

又或者

//DOM2級事件處理程序
var oDiv = document.getElementById('oDiv');

//非ie
oDiv.addEventListener("click",function(){
  alert("你點(diǎn)擊了我");
},false); 

//ie
oDiv.attachEvent("onclick", function(){
  alert("你點(diǎn)擊了我");
});

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

//跨瀏覽器的事件處理程序 
//調(diào)用時(shí)候直接用domEvent.addEvent( , , );直接調(diào)用 
//使用時(shí)候,先用addEvent添加事件,然后在handleFun里面直接寫其他函數(shù)方法,如getEvent; 
//addEventListener和attachEvent---都是dom2級事件處理程序 
var domEvent = { 
  //element:dom對象,event:待處理的事件,handleFun:處理函數(shù) 
  //事件名稱,不含“on”,比如“click”、“mouseover”、“keydown”等 
  addEvent:function(element,event,handleFun){ 
    //addEventListener----應(yīng)用于mozilla 
    if(element.addEventListener){ 
      element.addEventListener(event,handleFun,false); 
    }//attachEvent----應(yīng)用于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----應(yīng)用于mozilla 
    if (element.removeEventListener) { 
      element.removeEventListener(event,handleFun,false); 
    }//detachEvent----應(yīng)用于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代表阻止 
    } 
  }, 
  //阻止事件默認(rèn)行為 
  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自定義事件

根據(jù)上面的封裝,我們可以這樣構(gòu)思

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

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

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

我是這樣構(gòu)建這個(gè)映射關(guān)系的

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

這樣每一個(gè)類型可以有多個(gè)處理函數(shù),以便于我們以后擴(kuò)充
接下來就是代碼方面的實(shí)戰(zhàn)的,編寫具體的處理代碼了…

相信大家對于這個(gè)思路已經(jīng)很清楚了,我直接附上代碼

//直接量處理js自定義事件
var eventTarget = {
  //保存事件類型,處理函數(shù)數(shù)組映射
  handlers:{},
  //注冊給定類型的事件處理程序,
  //type -> 自定義事件類型, handler -> 自定義事件回調(diào)函數(shù)
  addEvent: function(type, handler){
    //判斷事件處理數(shù)組是否有該類型事件
    if(eventTarget.handlers[type] == undefined){
      eventTarget.handlers[type] = [];
    }
    //將處理事件push到事件處理數(shù)組里面
    eventTarget.handlers[type].push(handler);
  },
  //觸發(fā)一個(gè)事件
  //event -> 為一個(gè)js對象,屬性中至少包含type屬性,
  //因?yàn)轭愋褪潜仨毜模浯慰梢詡饕恍┨幚砗瘮?shù)需要的其他變量參數(shù)。(這也是為什么要傳js對象的原因)
  fireEvent: function(event){
    //判斷是否存在該事件類型
    if(eventTarget.handlers[event.type] instanceof Array){
      var _handler = eventTarget.handlers[event.type];
      //在同一個(gè)事件類型下的可能存在多種處理事件,找出本次需要處理的事件
      for(var i = 0; i < _handler.length; i++){
        //執(zhí)行觸發(fā)
        _handler[i](event);
      }
    }
  },
  //注銷事件
  //type -> 自定義事件類型, handler -> 自定義事件回調(diào)函數(shù)
  removeEvent: function(type, handler){
    if(eventTarget.handlers[type] instanceof Array){
      var _handler = eventTarget.handlers[type];
      //在同一個(gè)事件類型下的可能存在多種處理事件,找出本次需要處理的事件
      for(var i = 0; i < _handler.length; i++){
        //找出本次需要處理的事件下標(biāo)
        if(_handler[i] == handler){
          break;
        }
      }
      //刪除處理事件
      _handler.splice(i, 1);
    }
  }
};

這是一種調(diào)用運(yùn)行的方法

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

這種方法有一個(gè)缺點(diǎn),不能刪除該處理事件,因?yàn)槲覀兪怯糜成浔碜龅?,而且也不提倡,直接給映射表里面存這么多數(shù)據(jù),有點(diǎn)多。

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

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

也可以這樣,傳遞更多的參數(shù)

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

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

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

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

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

調(diào)用方法

function b(){
  console.log(123);
}

var target = new EventTarget();
target.addEvent("eat", b);

target.fireEvent({
  type: "eat"
});                 //123

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

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • AJAX使用了UpdatePanel后無法使用alert彈出腳本

    AJAX使用了UpdatePanel后無法使用alert彈出腳本

    今天在做項(xiàng)目的時(shí)候發(fā)現(xiàn)個(gè)問題。。使用UpdatePanel后alert腳本就要報(bào)錯(cuò)了。
    2010-04-04
  • JS清除選擇內(nèi)容的方法

    JS清除選擇內(nèi)容的方法

    這篇文章主要介紹了JS清除選擇內(nèi)容的方法,較為詳細(xì)的分析了js操作文本的技巧,需要的朋友可以參考下
    2015-01-01
  • 談?wù)処ntersectionObserver懶加載的具體使用

    談?wù)処ntersectionObserver懶加載的具體使用

    這篇文章主要介紹了談?wù)処ntersectionObserver懶加載的具體使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Cookie 注入是怎樣產(chǎn)生的

    Cookie 注入是怎樣產(chǎn)生的

    現(xiàn)在很多網(wǎng)站都加了防注入系統(tǒng)代碼,你輸入注入語句將無法注入~~感覺這樣的防注入系統(tǒng)不錯(cuò),但防注入系統(tǒng)沒有注意到 Cookies 的問題!所以就有了Cookies注入~~
    2009-04-04
  • javascript concat數(shù)組累加 示例

    javascript concat數(shù)組累加 示例

    javascript concat數(shù)組累加使用實(shí)例。
    2009-09-09
  • JavaScript計(jì)算正方形面積

    JavaScript計(jì)算正方形面積

    這篇文章主要為大家詳細(xì)介紹了JavaScript計(jì)算正方形面積,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • 淺談js中對象的使用

    淺談js中對象的使用

    下面小編就為大家?guī)硪黄獪\談js中對象的使用。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-08-08
  • typescript中聲明合并介紹

    typescript中聲明合并介紹

    這篇文章主要介紹了typescript中聲明合并介紹,類型合并表明編譯器將合并兩個(gè)分開的并且名稱相同的聲明,合并之后的聲明擁有兩個(gè)聲明的特點(diǎn),任意數(shù)量的聲明可以被合并,不僅限兩個(gè),更多相關(guān)內(nèi)容需要的朋友可以參考下面文章內(nèi)容
    2022-09-09
  • JavaScript中if嵌套assert的方法詳解

    JavaScript中if嵌套assert的方法詳解

    在JavaScript中,通常我們不會直接使用`assert`這個(gè)詞,因?yàn)镴avaScript標(biāo)準(zhǔn)庫中并沒有直接提供`assert`函數(shù),下面是一個(gè)詳細(xì)的示例,展示如何在JavaScript中模擬`assert`函數(shù),并在`if`語句中嵌套使用它來檢查條件,需要的朋友可以參考下
    2024-09-09
  • d3.js中冷門卻實(shí)用的內(nèi)置函數(shù)總結(jié)

    d3.js中冷門卻實(shí)用的內(nèi)置函數(shù)總結(jié)

    D3.js是一個(gè)JavaScript庫,它可以通過數(shù)據(jù)來操作文檔。D3可以通過使用HTML、SVG和CSS把數(shù)據(jù)鮮活形象地展現(xiàn)出來。d3.js其實(shí)提供了很多內(nèi)置的函數(shù),可以卻被大家忽略了,下面這篇文章就來給大家詳細(xì)介紹了d3.js中冷門卻實(shí)用的一些內(nèi)置函數(shù),需要的朋友可以參考借鑒。
    2017-02-02

最新評論

信阳市| 紫金县| 格尔木市| 克山县| 法库县| 宜良县| 游戏| 进贤县| 聂荣县| 宝坻区| 许昌市| 汤阴县| 稻城县| 昌平区| 泰宁县| 宜兴市| 葫芦岛市| 余江县| 娄烦县| 龙岩市| 无极县| 兰坪| 瑞丽市| 定日县| 瑞金市| 大兴区| 临邑县| 迁安市| 桂阳县| 双辽市| 河源市| 南汇区| 卢龙县| 郑州市| 文安县| 新田县| 冀州市| 潍坊市| 赫章县| 特克斯县| 丹棱县|