程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> js也可以有自定義事件 注入就是這麼爽

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

編輯:.NET實例教程

     在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對象,就更加靈活了)的完成了自定義事件。
  http://www.cnblogs.com/boolean/archive/2006/12/10/boolean.Html
  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved