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

首頁 > 開發 > 綜合 > 正文

js也可以有自定義事件 注入就是這么爽

2024-07-21 02:28:25
字體:
來源:轉載
供稿:網友


  在c#中有delegate,還有特殊的可以直接應用于事件編程的delegate,那就是event。而在js中沒有c#的event,更沒有delegate,有的只是dom元素內置的的native的不可擴展的event,比如無法為input元素添加事件,只能在其擁有的事件(如onclick=handler)上擴展應用。那么能不能做到自定義的事件模擬效果呢?答案是肯定的,也就是本文的主題。
  首先弄明白一下事件的意圖——可以在發生一件事的時候執行額外的代碼,如document.attachevent('onclick', function(){alert('u click document')}),當點擊頁面時(事件發生了),就會執行我們為其掛接的其它代碼(js中以function為語句集合,以下稱為function),當然我們可以在一個事件上掛接任意多的function,這樣就實現了一種靈活的可擴展編程接口。試想如果可以像在元素事件擴展應用一樣可以在任意對象的任意方法上擴展,那對于js編程來講就更加靈活了。先看一個例子,平時我們把相對對立的一個功能命名為一個function,并在需要的地方(通常是另一個function)調用以實現代碼復用:
function f(){
    this.method = function(){
        alert('f.method is called')
        g();
    }
}
function g(){
    alert(123)
}
var f = new f();
f.method()


我們把f.method中直接調用g改寫一下,封裝到一個event對象中達到一樣的效果,代碼如下:
var event = {
    __list:[],
    observe:function(obj, ev, fun){
        this.__list.push({o:obj, e:ev, f:fun})
    },
    occor:function(obj, method){
        var arr = []
        for(var i=0; i<this.__list.length; i++){
            if(this.__list[i].o==obj && this.__list[i].e==method) arr.push(this.__list[i]);
        }
        for(var i=0; i<arr.length; i++){
            arr[i].f();
        }
    }
}

function f(){
    this.method = function(){
        alert('f.method is called')
        event.occor(this, 'method');
    }
}

var f = new f();
event.observe(f, 'method', function(){alert(123)})
f.method()這樣乍看上去好像費了“太多”功夫,但卻把“在f中調用g的寫法”更通用化了,如果要在f中調用h則只需要多些一行event.occor(this, 'methodname'),寫到這里你肯定也注意到methodname的寫法和最開始的寫法是一樣的,都是硬編的不具靈活性,如果在每個類的方法中都寫入event.occor(this, 'method')就太不雅觀了,也背離了我們的初衷,動態修改一下method把它加到最后一行就ok了,下一步就是解決它,改進代碼如下:

var event = {
    __list:[],
    observe:function(obj, ev, fun){
        this.__list.push({o:obj, e:ev, f:fun})
    },
    occor:function(obj, method){
        var arr = []
        for(var i=0; i<this.__list.length; i++){
            if(this.__list[i].o==obj && this.__list[i].e==method) arr.push(this.__list[i]);
        }
        for(var i=0; i<arr.length; i++){
            arr[i].f();
        }
    },
    inject:function(obj){
        for(var p in obj){
            obj[p] = new function(obj[p].tostring().replace('function(){', '').replace('}', 'event.occor(this,p)'))
        }
    }
}

function f(){
    this.method = function(){
        alert('f.method is called')
    }
}

var f = new f();
event.inject(f);
event.observe(f, 'method', function(){alert(123)})
f.method()我們把顯示的在被調用方法體內調用event.occor改寫到event.inject中。到此我們就簡單(還有一些安全代碼沒有處理,如沒有判斷obj[p]是否需要被改寫、沒有測試效率問題,沒有處理更多添加event.occor時的邏輯判斷,下一步準備把它實現為一個observeable對象,就更加靈活了)的完成了自定義事件。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 都匀市| 旺苍县| 徐闻县| 松原市| 高阳县| 芷江| 古田县| 靖边县| 龙口市| 墨竹工卡县| 南雄市| 万安县| 宜良县| 横山县| 邵阳市| 安义县| 尼玛县| 宁明县| 新泰市| 顺义区| 湘阴县| 息烽县| 公主岭市| 松桃| 顺平县| 北京市| 绍兴市| 古田县| 丹东市| 宁武县| 南部县| 潮州市| 雷州市| 泽州县| 永和县| 苍梧县| 屏边| 铁岭县| 紫金县| 岳普湖县| 乌鲁木齐县|