<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 154  文章 - 60  trackbacks - 0
    <2007年10月>
    30123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    聲明:

    該blog是為了收集資料,認識朋友,學(xué)習(xí)、提高技術(shù),所以本blog的內(nèi)容除非聲明,否則一律為轉(zhuǎn)載!!

    感謝那些公開自己技術(shù)成果的高人們!!!

    支持開源,尊重他人的勞動!!

    常用鏈接

    留言簿(3)

    隨筆分類(148)

    隨筆檔案(143)

    收藏夾(2)

    其他

    學(xué)習(xí)(技術(shù))

    觀察思考(非技術(shù))

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    事件設(shè)計概述
    事件機制可以使程序邏輯更加符合現(xiàn)實世界,在JavaScript中很多對象都有自己的事件,例如按鈕就有onclick事件,下拉列表框就有onchange事件,通過這些事件可以方便編程。那么對于自己定義的類,是否也可以實現(xiàn)事件機制呢?是的,通過事件機制,可以將類設(shè)計為獨立的模塊,通過事件對外通信,提高了程序的開發(fā)效率。本節(jié)就將詳細介紹JavaScript中的事件設(shè)計模式以及可能遇到的問題。

    最簡單的事件設(shè)計模式
    最簡單的一種模式是將一個類的方法成員定義為事件,這不需要任何特殊的語法,通常是一個空方法,例如:
    function class1(){
          //構(gòu)造函數(shù)
    }
    class1.prototype={
          show:function(){
                //show函數(shù)的實現(xiàn)
                this.onShow();  //觸發(fā)onShow事件
          },
          onShow:function(){}  //定義事件接口
    }
    上面的代碼中,就定義了一個方法:show(),同時該方法中調(diào)用了onShow()方法,這個onShow()方法就是對外提供的事件接口,其用法如下:
    //創(chuàng)建class1的實例
    var obj=new class1();
    //創(chuàng)建obj的onShow事件處理程序
    obj.onShow=function(){
          alert("onshow event");
    }
    //調(diào)用obj的show方法
    obj.show();

    由此可見,obj.onShow方法在類的外部被定義,而在類的內(nèi)部方法show()中被調(diào)用,這就實現(xiàn)了事件機制。
    上述方法很簡單,實際的開發(fā)中常用來解決一些簡單的事件功能。說它簡單,因為它有以下兩個缺點:
    ? 不能夠給事件處理程序傳遞參數(shù),因為是在show()這個內(nèi)部方法中調(diào)用事件處理程序的,無法知道外部的參數(shù);
    ? 每個事件接口僅能夠綁定一個事件處理程序,而內(nèi)部方法則可以使用attachEvent或者addEventListener方法綁定多個處理程序。
    在下面兩小節(jié)將著重解決這個問題。

    給事件處理程序傳遞參數(shù)
    給事件處理程序傳遞參數(shù)不僅是自定義事件中存在的問題,也是系統(tǒng)內(nèi)部對象的事件機制中存在的問題,因為事件機制僅傳遞一個函數(shù)的名稱,不帶有任何參數(shù)的信息,所以無法傳遞參數(shù)進去。例如:
    //定義類class1
    function class1(){
          //構(gòu)造函數(shù)
    }
    class1.prototype={
          show:function(){
                //show函數(shù)的實現(xiàn)
                this.onShow();  //觸發(fā)onShow事件
          },
          onShow:function(){}  //定義事件接口
    }
    //創(chuàng)建class1的實例
    var obj=new class1();
    //創(chuàng)建obj的onShow事件處理程序
    function objOnShow(userName){
           alert("hello,"+userName);
    }
    //定義變量userName
    var userName="jack";
    //綁定obj的onShow事件
    obj.onShow=objOnShow;  //無法將userName這個變量傳遞進去
    //調(diào)用obj的show方法
    obj.show();
    注意上面的obj.onShow=objOnShow事件綁定語句,不能為了傳遞userName變量進去而寫成:
    obj.onShow=objOnShow(userName);
    或者:
    obj.onShow="objOnShow(userName)";
    前者是將objOnShow(userName)的運行結(jié)果賦給了obj.onShow,而后者是將字符串“objOnShow(userName)”賦給了obj.onShow。
    要解決這個問題,可以從相反的思路去考慮,不考慮怎么把參數(shù)傳進去,而是考慮如何構(gòu)建一個無需參數(shù)的事件處理程序,該程序是根據(jù)有參數(shù)的事件處理程序創(chuàng)建的,是一個外層的封裝。現(xiàn)在自定義一個通用的函數(shù)來實現(xiàn)這種功能:
    //將有參數(shù)的函數(shù)封裝為無參數(shù)的函數(shù)
    function createFunction(obj,strFunc){
          var args=[];      //定義args用于存儲傳遞給事件處理程序的參數(shù)
          if(!obj)obj=window;     //如果是全局函數(shù)則obj=window;
          //得到傳遞給事件處理程序的參數(shù)
          for(var i=2;i<arguments.length;i++)args.push(arguments[i]);
          //用無參數(shù)函數(shù)封裝事件處理程序的調(diào)用
          return function(){
                obj[strFunc].apply(obj,args); //將參數(shù)傳遞給指定的事件處理程序
          }
    }
    該方法將一個有參數(shù)的函數(shù)封裝為一個無參數(shù)的函數(shù),不僅對全局函數(shù)適用,作為對象方法存在的函數(shù)同樣適用。該方法首先接收兩個參數(shù):obj和strFunc,obj表示事件處理程序所在的對象;strFunc表示事件處理程序的名稱。除此以外,程序中還利用arguments對象處理第二個參數(shù)以后的隱式參數(shù),即未定義形參的參數(shù),并在調(diào)用事件處理程序時將這些參數(shù)傳遞進去。例如一個事件處理程序是:
    someObject.eventHandler=function(_arg1,_arg2){
         //事件處理代碼
    }
    應(yīng)該調(diào)用:
    createFunction(someObject,"eventHandler",arg1,arg2);
    這就返回一個無參數(shù)的函數(shù),在返回的函數(shù)中已經(jīng)包括了傳遞進去的參數(shù)。如果是全局函數(shù)作為事件處理程序,事實上它是window對象的一個方法,所以可以傳遞window對象作為obj參數(shù),為了更清晰一點,也可以指定obj為null,createFunction函數(shù)內(nèi)部會自動認為該函數(shù)是全局函數(shù),從而自動把obj賦值為window。下面來看應(yīng)用的例子:
    <script language="JavaScript" type="text/javascript">
    <!--
    //將有參數(shù)的函數(shù)封裝為無參數(shù)的函數(shù)
    function createFunction(obj,strFunc){
          var args=[];
          if(!obj)obj=window;
          for(var i=2;i<arguments.length;i++)args.push(arguments[i]);
          return function(){
                obj[strFunc].apply(obj,args);
          }
    }
    //定義類class1
    function class1(){
          //構(gòu)造函數(shù)
    }
    class1.prototype={
          show:function(){
                //show函數(shù)的實現(xiàn)
                this.onShow();  //觸發(fā)onShow事件
          },
          onShow:function(){} //定義事件接口
    }
    //創(chuàng)建class1的實例
    var obj=new class1();
    //創(chuàng)建obj的onShow事件處理程序
    function objOnShow(userName){
          alert("hello,"+userName);
    }
    //定義變量userName
    var userName="jack";
    //綁定obj的onShow事件
    obj.onShow=createFunction(null,"objOnShow",userName);
    //調(diào)用obj的show方法
    obj.show();
    //-->
    </script>
    在這段代碼中,就將變量userName作為參數(shù)傳遞給了objOnShow事件處理程序。事實上,obj.onShow得到的事件處理程序并不是objOnShow,而是由createFunction返回的一個無參函數(shù)。
    通過createFunction封裝,就可以用一種通用的方案實現(xiàn)參數(shù)傳遞了。這不僅適用于自定義的事件,也適用于系統(tǒng)提供的事件,其原理是完全相同的。


    使自定義事件支持多綁定
    可以用attachEvent或者addEventListener方法來實現(xiàn)多個事件處理程序的同時綁定,不會互相沖突,而自定義事件怎樣來實現(xiàn)多訂閱呢?下面介紹這種實現(xiàn)。要實現(xiàn)多訂閱,必定需要一個機制用于存儲綁定的多個事件處理程序,在事件發(fā)生時同時調(diào)用這些事件處理程序。從而達到多訂閱的效果,其實現(xiàn)如下:
    <script language="JavaScript" type="text/javascript">
    <!--
    //定義類class1
    function class1(){
          //構(gòu)造函數(shù)
    }
    //定義類成員
    class1.prototype={
          show:function(){
               //show的代碼
               //...

               //如果有事件綁定則循環(huán)onshow數(shù)組,觸發(fā)該事件
               if(this.onshow){
                      for(var i=0;i<this.onshow.length;i++){
                            this.onshow[i](); //調(diào)用事件處理程序
                      }
               }
          },
          attachOnShow:function(_eHandler){
                if(!this.onshow)this.onshow=[]; //用數(shù)組存儲綁定的事件處理程序引用
                this.onshow.push(_eHandler);
          }
    }
    var obj=new class1();
    //事件處理程序1
    function onShow1(){
          alert(1);
    }
    //事件處理程序2
    function onShow2(){
          alert(2);
    }
    //綁定兩個事件處理程序
    obj.attachOnShow(onShow1);
    obj.attachOnShow(onShow2);
    //調(diào)用show,觸發(fā)onshow事件
    obj.show();
    //-->
    </script>
    從代碼的執(zhí)行結(jié)果可以看到,綁定的兩個事件處理程序都得到了正確的運行。如果要綁定有參數(shù)的事件處理程序,只需加上createFunction方法即可,在上一節(jié)有過描述。
    這種機制基本上說明了處理多事件處理程序的基本思想,但還有改進的余地。例如如果類有多個事件,可以定義一個類似于attachEvent的方法,用于統(tǒng)一處理事件綁定。在添加了事件綁定后如果想刪除,還可以定義一個detachEvent方法用于取消綁定。這些實現(xiàn)的基本思想都是對數(shù)組的操作。

    posted on 2007-10-09 09:41 lk 閱讀(262) 評論(0)  編輯  收藏 所屬分類: ajax&js
    主站蜘蛛池模板: 亚洲网址在线观看| 亚洲国产精品久久久天堂| 亚洲性色成人av天堂| 91成人在线免费观看| 久久国产精品亚洲综合| 国产免费爽爽视频在线观看| 亚洲欭美日韩颜射在线二| 中文在线观看国语高清免费| 狠狠亚洲狠狠欧洲2019| 中文字幕无码免费久久9一区9| 亚洲色偷偷综合亚洲AVYP| 青青操免费在线视频| 亚洲AV人无码综合在线观看| 一级毛片免费毛片一级毛片免费 | 精品国产免费一区二区| 亚洲av无码偷拍在线观看| 又黄又大又爽免费视频| 免费人成视频在线播放| 亚洲自偷自偷偷色无码中文| 你好老叔电影观看免费| 久久亚洲精品无码aⅴ大香| 97在线观看永久免费视频| 亚洲狠狠成人综合网| 国产亚洲福利一区二区免费看| 国产无遮挡色视频免费观看性色| 日韩一卡2卡3卡4卡新区亚洲| 国产真人无码作爱免费视频| 亚洲美女视频免费| 日本不卡免费新一二三区| 国产精品美女免费视频观看| 亚洲av综合avav中文| 国产成在线观看免费视频| 免费精品国产自产拍在线观看| 亚洲av午夜成人片精品电影| 久久久久久国产精品免费免费男同 | 免费a在线观看播放| 国产免费一区二区三区不卡| 亚洲视频免费一区| 国产jizzjizz视频免费看| 精品在线免费观看| 亚洲欧洲国产综合AV无码久久|