JavaScript中自定义事件用法分析
本文实例讲述了JavaScript中自定义事件用法。分享给大家供大家参考。具体分析如下:
在web前端开发中,很多人可能不会用到js的自定义事件,但如果是做一个相对来说比较大的项目,尤其是多人协同开发的时候,自定义事件就显得很重要了。那么,什么是js中的自定义事件呢?我们先来看一个例子:
前端开发员A封装了一个函数:
functionmove(){
alert(a); //以此来代表N行代码
}过段时间,前端开发员B要在A的基础上丰富这个函数,于是,他会这样写:
functionmove(){
alert(a); //以此来代表N行代码
alert(b); //以此来代表N行代码
}是不是发现了问题,B要注意和A的变量、函数等等的命名和冲突问题,又过段时间,前端开发员C也要丰富这个函数,于是:
functionmove(){
alert(a); //以此来代表N行代码
alert(b); //以此来代表N行代码
alert(c); //以此来代表N行代码
}这时候会很令人抓狂了,C写起代码来我敢肯定不会很轻松。解决这个问题的方法就是通过自定义事件,我们知道一个元素身上可以添加相同的事件而不会各自影响,如:
window.addEventListener('click',function(){
alert(1);
},false);
window.addEventListener('click',function(){
alert(2);
},false);点击页面的时候,1和2都会弹出,那么我们就可以用这种方法来定义我们的函数:
window.addEventListener('move',function(){
alert(3);
},false);
window.addEventListener('move',function(){
alert(4);
},false);这样,我们执行move();的时候就会弹出3和4,这里的move就是自定义事件,它其实就是一个函数
下面看看如何给事件处理程序传递参数:
//将有参数的函数封装为无参数的函数
functioncreateFunction(obj,strFunc){
varargs=[]; //定义args用于存储传递给事件处理程序的参数
if(!obj)obj=window;//如果是全局函数则obj=window;
//得到传递给事件处理程序的参数
for(vari=2;i<arguments.length;i++)args.push(arguments[i]);
//用无参数函数封装事件处理程序的调用
returnfunction(){
obj[strFunc].apply(obj,args);//将参数传递给指定的事件处理程序
}
}
functionclass1(){
}
class1.prototype={
show:function(){
this.onShow();
},
onShow:function(){}
}
functionobjOnShow(userName){
alert("hello,"+userName);
}
functiontest(){
varobj=newclass1();
varuserName="test";
obj.onShow=createFunction(null,"objOnShow",userName);
obj.show();
}
"因为事件机制仅传递一个函数的名称,不带有任何参数的信息,所以无法传递参数进去",这是后话了,“要解决这个问题,可以从相反的思路去考虑,不考虑怎么把参数传进去,而是考虑如何构建一个无需参数的事件处理程序,该程序是根据有参数的事件处理程序创建的,是一个外层的封装。”,这里的“该程序”就是createFunction函数,它巧妙地利用apply函数将带参数的函数封装为无参数函数。最后我们看看如何实现自定义事件的多绑定:
//使自定义事件支持多绑定
//将有参数的函数封装为无参数的函数
functioncreateFunction(obj,strFunc){
varargs=[]; //定义args用于存储传递给事件处理程序的参数
if(!obj)obj=window;//如果是全局函数则obj=window;
//得到传递给事件处理程序的参数
for(vari=2;i<arguments.length;i++)args.push(arguments[i]);
//用无参数函数封装事件处理程序的调用
returnfunction(){
obj[strFunc].apply(obj,args);//将参数传递给指定的事件处理程序
}
}
functionclass1(){
}
class1.prototype={
show:function(){
if(this.onShow){
for(vari=0;i<this.onShow.length;i++){
this.onShow[i]();
}
}
},
attachOnShow:function(_eHandler){
if(!this.onShow){this.onShow=[];}
this.onShow.push(_eHandler);
}
}
functionobjOnShow(userName){
alert("hello,"+userName);
}
functionobjOnShow2(testName){
alert("show:"+testName);
}
functiontest(){
varobj=newclass1();
varuserName="yourname";
obj.attachOnShow(createFunction(null,"objOnShow",userName));
obj.attachOnShow(createFunction(null,"objOnShow2","testmessage"));
obj.show();
}我们看到,attachOnShow方法实现的基本思想是对数组的push操作,其实我们还可以在事件执行完成之后,移除事件处理函数,下面单独实现:
//将有参数的函数封装为无参数的函数
functioncreateFunction(obj,strFunc){
varargs=[]; //定义args用于存储传递给事件处理程序的参数
if(!obj)obj=window;//如果是全局函数则obj=window;
//得到传递给事件处理程序的参数
for(vari=2;i<arguments.length;i++)args.push(arguments[i]);
//用无参数函数封装事件处理程序的调用
returnfunction(){
obj[strFunc].apply(obj,args);//将参数传递给指定的事件处理程序
}
}
functionclass1(){
}
class1.prototype={
show:function(){
if(this.onShow){
for(vari=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);
}
}
functionobjOnShow(userName){ alert("hello,"+userName); } functionobjOnShow2(testName){ alert("show:"+testName); } functiontest(){ varobj=newclass1(); varuserName="yourname"; obj.attachOnShow(createFunction(null,"objOnShow",userName)); obj.attachOnShow(createFunction(null,"objOnShow2","testmessage")); obj.show(); obj.detachOnShow(createFunction(null,"objOnShow",userName)); obj.show();//移除一个,显示剩余的一个 obj.detachOnShow(createFunction(null,"objOnShow2","testmessage")); obj.show();//两个都移除,一个也不显示 }