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

Javascript自定義事件詳解

 更新時間:2017年01月13日 10:10:28   作者:猴子  
這篇文章主要介紹了Javascript自定義事件,本質就是觀察者模式,好處就是將綁定事件和觸發(fā)事件相互隔離開等等,具有一定的參考價值,感興趣的小伙伴們可以參考一下

Javascript自定義事件,其本質就是觀察者模式(又稱訂閱/發(fā)布模式),它的好處就是將綁定事件和觸發(fā)事件相互隔離開,并且可以動態(tài)的添加、刪除事件。

下面通過實例,一步一步構建一個具體的Javascript自定義事件對象。

如:我有一個action1函數(shù),我想每次在執(zhí)行完action1后,觸發(fā)另一個函數(shù)service1,那么代碼我們可以這么寫:

//服務service1
function service1(){

}
//函數(shù)action1
function action1(){
 //other things
 //then 啟動service1
 service1();
}

Good,但是現(xiàn)在想法變了,我想在action1完成后,不僅觸發(fā)service1,還要觸發(fā)service2和service3。

按照剛才的思路,在函數(shù)action1完成后,順帶加上它們就是了。

如下:

function service1(){}
function service2(){}
function service3(){}

function action1(){
 //other things 
 service1();
 service2();
 service3();
}

但,想法又再次發(fā)生波動,在執(zhí)行完action1函數(shù)后,我突然想動態(tài)添加一個service4,且,發(fā)現(xiàn)service2似乎毫無意義,我不想觸發(fā)了,怎么辦呢?

你可能會說去掉service2,然后在action1后面加入service4不就完了嗎?

但是,在真正的項目開發(fā)代碼日益劇增的情況下,談何容易,還要去找到相關代碼進行操作。

那怎么辦呢?

初步想法,定義一個數(shù)組嘛(如:servicearray),用來管理所有的service。

當action1執(zhí)行到末尾后,遍歷一遍這個數(shù)組函數(shù)(servicearray),就歐克了嘛。

且,倘若我們不想運行service2了,便將它從這個數(shù)組中刪除就好了;倘若想再添加一個新的service,將其追加到servicearray數(shù)組中就好了。

如此nice,如下:

var servicearray = [];

function service1(){}
function service2(){}
function service3(){}
//將所有service添加到servicearray中
servicearray.push(service1);
servicearray.push(service2);
servicearray.push(service3);
//del:用于刪除一個指定的service
function del(arr, fn){
 for(var i = 0; i < arr.length; i++){
  if( arr[i] == fn ){
   arr.splice(i,1);
   break;
  }
 } 
}
//action1后,執(zhí)行所有的service
function action1(){
 //other things 
 //遍歷serviceaary,執(zhí)行所有service函數(shù)。(servicearray在action1內)
 for(var i =0; i < servicearray.length; i++){
  servicearray[i]();
 }
}
//添加service4
function service4(){}
servicearray.push(service4);
//刪除service2
del(servicearray, service2);

上面代碼挺歐克的,但,復用性一點都不強,且servicearray與action你中有我,我中有你,不好。我們再來優(yōu)化優(yōu)化。

代碼如下:

var servicearray = [];

function service1(){}
function service2(){}
function service3(){}

servicearray.push(service1);
servicearray.push(service2);
servicearray.push(service3);
function del(arr, fn){
 for(var i = 0; i < arr.length; i++){
  if( arr[i] == fn ){
   arr.splice(i,1);
   break;
  }
 } 
}
//添加一個service4
function service4(){}
servicearray.push(service4);
//刪除一個service2
del(servicearray, service2);
//添加一個觸發(fā)函數(shù)hanldeAction,分離action與service
function hanldeAction(actionName,serviceArr){
 if(typeof actionName === 'function'){
  actionName();
  for(var i =0; i < serviceArr.length; i++){
   serviceArr[i]();
  }
 }
}
//執(zhí)行
handleAction(action1,servicearray); 

上面的代碼和回調函數(shù)有異曲同工之處,因為我們想達到的效果是在 action執(zhí)行完成之后,運行一系列service嘛。

但,我現(xiàn)在改變想法了,我想在action執(zhí)行之前執(zhí)行一系列service呢,或者action中呢。看來得改hanldeAction回調函數(shù)啊,這放在項目中反復修改,顯然不行。

所以,我們得讓其更強大才好。(我想讓它在什么地方執(zhí)行就執(zhí)行)

如下:

function service1(){}
function service2(){}
function service3(){}

var servicearray = [];
servicearray.push(service1);
servicearray.push(service2);
servicearray.push(service3);
function del(arr, fn){
 for(var i = 0; i < arr.length; i++){
  if( arr[i] == fn ){
   arr.splice(i,1);
   break;
  }
 } 
}
//添加一個service4
function service4(){}
servicearray.push(service4);
//刪除一個service2
del(servicearray, service2);
/*
 actionObj用于存儲所有action與service關聯(lián)的對象。
 如:{
   action1:[service1,service2],
   action2:[...]
  }
*/
var actionObj = {};
/*
 修改代碼,增加一個actionName與serviceArr關聯(lián)事件。
 如,action1關聯(lián)所有service,這樣再結合下方的trigger事件就完美了
 Params:
   actionName --> actionObj的屬性
   serviceArr --> 包含所有與actionName相關的service數(shù)組
*/
function addAction(actionName, serviceArr){
 if(typeof actionObj[actionName] === 'undefined' ){
  actionObj[actionName] = [];
 }
 if(typeof serviceArr === 'object'){
  actionObj[actionName].push(serviceArr);
 }
}
/*
 修改代碼,增加一個觸發(fā)actionName事件
 如,當我想觸發(fā)action1中的所有service時,調用trigger(action1)就OK啦
*/
function trigger( actionName ){
 var act = actionObj[actionName];
 if(act instanceof Array){
  for(var i = 0, len = act.length; i < len; i++){
   for(var j =0, arrlen = act[i].length; j++){
    ((act[i])[j])();
   }
  }
 }
}

上述代碼是可以,但,有個性能問題,addAction中添加到actionObj[actionName]中的是一個數(shù)組,其實完全可以將定義的servicearray數(shù)組(為了存儲不同的service而聲明的數(shù)組)移除,轉而將每個service直接push進actionObj[actionName]聲明的數(shù)組中,這樣trigger事件效率也得到了提高,從原來的兩層for循環(huán)降到一層for循環(huán)。且,我們再加一個刪除service的方法remove。

整理代碼如下:

var actionObj = {};
//修改代碼,增加一個actionName與service函數(shù)直接關聯(lián)事件
function addAction(actionName, fn){
 if(typeof actionObj[actionName] === 'undefined' ){
  actionObj[actionName] = [];
 }
 if(typeof fn === 'function'){
  actionObj[actionName].push(fn);
 }
}
//修改代碼,增加一個觸發(fā)actionName事件
function trigger( actionName ){
 var actionarray = actionObj[actionName];
 if(actionarray instanceof Array){
  for(var i = 0, len = actionarray.length; i < len; i++){
   if(typeof actionarray[i] === 'function'){
    actionarray[i]();
   }
  }
 }
}
//修改代碼,增加一個刪除actionName中的service事件
function remove(actionName, fn){
 var actionarray = actionObj[actionName];
 if(typeof actionName === 'string' && actionarray instanceof Array){
  if(typeof fn === 'function'){
   //清除actionName中對應的fn方法
   for(var i=0, len = actionarray.length; i < len; i++){
    if(actionarray[i] === fn){
     actionObj[actionName].splice(i,1);
    }
   }
  }
 }
}

上面的代碼好是好,action與service也互不影響,也完成了它的使命。

使命?

這就是我們一起編寫的自定義事件嘛。是不是很簡單。

哈哈哈,我也在代碼中用到設計模式了(觀察者模式)。

一鼓作氣,我們再來優(yōu)化下上面的代碼。有沒有注意,我們是使用的全局變量,在模塊化開發(fā)的大環(huán)境下,我們居然在用全局變量,豈不是污染命名空間嘛。再改改。

修改代碼如下:

var EventTarget = function(){
 this.listener = {};
}
EventTarget.prototype = {
 constructor:EventTarget,
 addAction: function(actionName, fn){
  if(typeof actionName === 'string' && typeof fn === 'function'){
   //如果不存在actionName,就新建一個
   if(typeof this.listener[actionName] === 'undefined'){
    this.listener[actionName] = [fn];
   }
   //否則,直接往相應actinoName里面塞
   else{
    this.listener[actionName].push(fn);
   }
  }
 },
 trigger: function(actionName){
  var actionArray = this.listener[actionName];
  //觸發(fā)一系列actionName里的函數(shù)
  if(actionArray instanceof Array){
   for(var i = 0, len = actionArray.length; i < len; i++){
    if(typeof actionArray[i] === 'function'){
     actionArray[i]();
    }
   } 
  }
  actionArray = null;
 },
 remove: function(actionName, fn){
  var actionArray = this.listener[actionName];
  if(typeof actionName === 'string' && actionArray instanceof Array){
   if(typeof fn === 'function'){
    //清除actionName中對應的fn方法
    for(var i=0, len = actionArray.length; i < len; i++){
     if(actionArray[i] === fn){
      this.listener[actionName].splice(i,1);
     }
    }
   }
  }
  actionArray = null;
 }
};

一個JavaScript自定義事件新鮮出爐。

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

相關文章

  • javascript中export?和export?default的區(qū)別

    javascript中export?和export?default的區(qū)別

    本文主要介紹了javascript中export?和export?default的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • 實現(xiàn)iframe延時加載

    實現(xiàn)iframe延時加載

    實現(xiàn)iframe延時加載...
    2006-10-10
  • MQTT.js 入門使用教程

    MQTT.js 入門使用教程

    MQTT.js?是一個開源的?MQTT 協(xié)議的客戶端庫,使用 JavaScript 編寫,主要用于 Node.js 和 瀏覽器環(huán)境中,這篇文章主要介紹了MQTT.js 入門教程,需要的朋友可以參考下
    2023-04-04
  • 淺析JavaScript中的CSS屬性及命名規(guī)范

    淺析JavaScript中的CSS屬性及命名規(guī)范

    這篇文章主要介紹了JavaScript中的CSS屬性及命名規(guī)范。需要的朋友可以過來參考一下,希望對大家有所幫助
    2013-11-11
  • javascript 改變字體大小方法集合

    javascript 改變字體大小方法集合

    給網(wǎng)頁正文提供,小 中 大 三種字體的切換功能。用js代碼設置div style的fontSize屬性。
    2009-06-06
  • 特想搞點新的創(chuàng)意出來-立體方塊

    特想搞點新的創(chuàng)意出來-立體方塊

    特想搞點新的創(chuàng)意出來-立體方塊...
    2007-06-06
  • Div自動滾動到末尾的代碼

    Div自動滾動到末尾的代碼

    非常不錯的思路,自動滾動到div末尾
    2008-10-10
  • JavaScript函數(shù)返回值的具體使用

    JavaScript函數(shù)返回值的具體使用

    本文主要介紹了JavaScript函數(shù)返回值,包括基本返回值、多返回值、異步函數(shù)的返回值等,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-01-01
  • JavaScript中你不知道的Object.entries用法

    JavaScript中你不知道的Object.entries用法

    大家應該都知道,Object.entries()方法返回一個給定對象自身可枚舉屬性的鍵值對數(shù)組,其排列與使用 for...in 循環(huán)遍歷該對象時返回的順序一致,這篇文章主要給大家介紹了關于JavaScript中你不知道的Object.entries用法的相關資料,需要的朋友可以參考下
    2021-10-10
  • 深入解析js輪播插件核心代碼的實現(xiàn)過程

    深入解析js輪播插件核心代碼的實現(xiàn)過程

    這篇文章主要深度揭密了js輪播插件核心代碼的實現(xiàn)過程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04

最新評論

英超| 盖州市| 库伦旗| 会理县| 咸丰县| 安庆市| 武穴市| 新晃| 昌邑市| 佛学| 鹤山市| 永川市| 岚皋县| 湖州市| 双牌县| 开阳县| 怀安县| 资中县| 富锦市| 龙岩市| 调兵山市| 鲜城| 农安县| 南川市| 汽车| 博爱县| 永靖县| 新兴县| 福海县| 扬州市| 山东省| 临潭县| 富锦市| 邹城市| 大同市| 泰和县| 于田县| 原平市| 泰州市| 景德镇市| 易门县|