javascript:自定义事件初探

 "事件机制可以使程序逻辑更加符合现实世界,在JavaScript 中很多对象都有自己的事件,例如按钮就有onclick 事件,下拉列表框就有onchange 事件,通过这些事件可以方便编程。",还有,“通过事件机制,可以将类设计为独立的模块,通过事件对外通信,提高了程序的开发效率。”。相信C#程序员对 事件的好处是深有体会的。好了,Code is cheap.看代码:

function  class1() {  //  最简单的事件设计模式

}

class1.prototype 
=  {
    show: 
function () {
        
this .onShow();
    },
    onShow: 
function () { }
}

function  test() {
    
var  obj  =   new  class1();
    obj.onShow 
=   function () {
        alert(
" test " );
    }
    obj.show();
}

 

下面看看如何给事件处理程序传递参数:

 

// 将有参数的函数封装为无参数的函数 
function  createFunction(obj, strFunc) {
    
var  args  =  [];        // 定义args 用于存储传递给事件处理程序的参数 
     if  ( ! obj) obj  =  window;  // 如果是全局函数则obj=window; 
     // 得到传递给事件处理程序的参数 
     for  ( var  i  =   2 ; i  <  arguments.length; i ++ ) args.push(arguments[i]);
    
// 用无参数函数封装事件处理程序的调用 
     return   function () {
        obj[strFunc].apply(obj, args); 
// 将参数传递给指定的事件处理程序 
    }
}

function  class1() {

}

class1.prototype 
=  {
    show: 
function () {
        
this .onShow();
    },
    onShow: 
function () { }
}

function  objOnShow(userName) {
    alert(
" hello, "   +  userName);
}

function  test() {
    
var  obj  =   new  class1();
    
var  userName  =   " test " ;
    obj.onShow 
=  createFunction( null " objOnShow " , userName);
    obj.show();
}

 

"因为事件机制仅传递一个函数的名称,不带有任何参数的信息,所以无法传递参数进去",这是后话了,“要解决这个问题,可以从相反的思路去考虑,不考虑怎 么把参数传进去,而是考虑如何构建一个无需参数的事件处理程序,该程序是根据有参数的事件处理程序创建的,是一个外层的封装。”,这里的“该程序”就是 createFunction函数,它巧妙地利用apply函数将带参数的函数封装为无参数函数。最后我们看看如何实现自定义事件的多绑定:

 

//  使自定义事件支持多绑定

// 将有参数的函数封装为无参数的函数 
function  createFunction(obj, strFunc) {
    
var  args  =  [];        // 定义args 用于存储传递给事件处理程序的参数 
     if  ( ! obj) obj  =  window;  // 如果是全局函数则obj=window; 
     // 得到传递给事件处理程序的参数 
     for  ( var  i  =   2 ; i  <  arguments.length; i ++ ) args.push(arguments[i]);
    
// 用无参数函数封装事件处理程序的调用 
     return   function () {
        obj[strFunc].apply(obj, args); 
// 将参数传递给指定的事件处理程序 
    }
}

function  class1() {

}

class1.prototype 
=  {
    show: 
function () {
        
if  ( this .onShow) {
            
for  ( var  i  =   0 ; i  <   this .onShow.length; i ++ ) {
                
this .onShow[i]();
            }
        }
    },
    attachOnShow: 
function (_eHandler) {
        
if  ( ! this .onShow) {  this .onShow  =  []; }
        
this .onShow.push(_eHandler);
    }
}

function  objOnShow(userName) {
    alert(
" hello, "   +  userName);
}

function  objOnShow2(testName) {
    alert(
" show: "   +  testName);
}

function  test() {
    
var  obj  =   new  class1();
    
var  userName  =   " your name " ;
    obj.attachOnShow(createFunction(
null " objOnShow " , userName));
    obj.attachOnShow(createFunction(
null " objOnShow2 " " test message " ));
    obj.show();
}

 

我们看到,attachOnShow方法实现的基本思想是对数组的push操作,其实我们还可以在事件执行完成之后,移除事件处理函数,下面单独实现:

 

// 将有参数的函数封装为无参数的函数 
function  createFunction(obj, strFunc) {
    
var  args  =  [];        // 定义args 用于存储传递给事件处理程序的参数 
     if  ( ! obj) obj  =  window;  // 如果是全局函数则obj=window; 
     // 得到传递给事件处理程序的参数 
     for  ( var  i  =   2 ; i  <  arguments.length; i ++ ) args.push(arguments[i]);
    
// 用无参数函数封装事件处理程序的调用 
     return   function () {
        obj[strFunc].apply(obj, args); 
// 将参数传递给指定的事件处理程序 
    }
}

function  class1() {

}

class1.prototype 
=  {
    show: 
function () {
        
if  ( this .onShow) {
            
for  ( var  i  =   0 ; i  <   this .onShow.length; i ++ ) {
                
this .onShow[i]();
            }
        }
    },
    attachOnShow: 
function (_eHandler) {  //  附加事件
         if  ( ! this .onShow) {  this .onShow  =  []; }
        
this .onShow.push(_eHandler);
    },
    detachOnShow: 
function (_eHandler) {  //  移除事件
         if  ( ! this .onShow) {  this .onShow  =  []; }
        
this .onShow.pop(_eHandler);
    }
}


function  objOnShow(userName) {
    alert(
" hello, "   +  userName);
}

function  objOnShow2(testName) {
    alert(
" show: "   +  testName);
}

function  test() {
    
var  obj  =   new  class1();
    
var  userName  =   " your name " ;
    obj.attachOnShow(createFunction(
null " objOnShow " , userName));
    obj.attachOnShow(createFunction(
null " objOnShow2 " " test message " ));
    obj.show();
    obj.detachOnShow(createFunction(
null " objOnShow " , userName));
    obj.show(); 
//  移除一个,显示剩余的一个
    obj.detachOnShow(createFunction( null " objOnShow2 " " test message " ));
    obj.show(); 
//  两个都移除,一个也不显示
}

 

关于自定义事件的学习先到这里。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值