麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

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

2019-11-18 16:49:27
字體:
供稿:網(wǎng)友

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


我們把f.method中直接調(diào)用g改寫一下,封裝到一個Event對象中達(dá)到一樣的效果,代碼如下:
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èi)了“太多”功夫,但卻把“在f中調(diào)用g的寫法”更通用化了,如果要在f中調(diào)用h則只需要多些一行Event.occor(this, 'methodName'),寫到這里你肯定也注意到methodName的寫法和最開始的寫法是一樣的,都是硬編的不具靈活性,如果在每個類的方法中都寫入Event.occor(this, 'method')就太不雅觀了,也背離了我們的初衷,動態(tài)修改一下method把它加到最后一行就ok了,下一步就是解決它,改進(jìn)代碼如下:

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()我們把顯示的在被調(diào)用方法體內(nèi)調(diào)用Event.occor改寫到Event.inject中。到此我們就簡單(還有一些安全代碼沒有處理,如沒有判斷obj[p]是否需要被改寫、沒有測試效率問題,沒有處理更多添加Event.occor時的邏輯判斷,下一步準(zhǔn)備把它實(shí)現(xiàn)為一個Observeable對象,就更加靈活了)的完成了自定義事件。
http://www.companysz.com/boolean/archive/2006/12/10/boolean.html


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 999久久国精品免费观看网站 | 一区二区三区日韩精品 | 线观看免费完整aaa 久久不雅视频 | 黄色免费在线网址 | 一级黄片毛片免费看 | 一本色道久久综合狠狠躁篇适合什么人看 | www.com香蕉 | 精品国产乱码久久久久久丨区2区 | 欧美成人精品一区二区三区 | 国产色视频免费 | 国产欧美在线一区二区三区 | 综合在线视频 | 欧美性生交大片 | 一级空姐毛片 | 日日综合 | 精品一区二区久久久久久按摩 | 久久久久久久久久久国产精品 | 国产高潮好爽受不了了夜色 | 成人区一区二区三区 | 久久免费激情视频 | www.91sp| 羞羞电影网 | 97中文字幕在线观看 | 国产成人精品免费视频大全办公室 | 萌白酱福利视频在线网站 | 天天看天天摸天天操 | 欧美精品| 国产九九热 | 国产欧美在线一区二区三区 | 毛片在线免费观看网址 | 精品国产一区二区在线 | 久久免费视频精品 | 国产午夜免费福利 | 久久免费看片 | 国产91丝袜在线播放 | www.69色| 看毛片免费 | 天天透天天狠天天爱综合97 | 在线中文日韩 | 日韩精品a在线观看 | 欧美亚洲国产一区二区三区 |