手机版

JavaScript自定义事件介绍

时间:2021-11-16 来源:互联网 编辑:宝哥软件园 浏览:

很多数字正射影像图对象都有原生的事件支持,向差异就有点击、鼠标悬停等事件,事件机制可以为类的设计带来很大的灵活性,相信。网程序员深有体会。随着网技术发展,使用Java脚本语言自定义对象愈发频繁,让自己创建的对象也有事件机制,通过事件对外通信,能够极大提高开发效率。简单的事件需求事件并不是可有可无,在某些需求下是必需的。以一个很简单的需求为例,在网开发中对话很常见,每个对话都有一个关闭按钮,按钮对应对话的关闭方法,代码看起来大概是这样复制代码代码如下:DOCTYPE html html head title TeSt/title style type=' text/CSS ' .对话框{位置:固定宽度宽度:300像素高度:300 pxz索引:30;前:50%;左侧:50%;边距-top :-200 px;边距-左侧:-200像素;盒影:2 px 2px 4px # CCC背景-color : # f1 f1;display:none}。对话标题{ font-size :16 px字体粗细:加粗;color: # fffpadding:4px背景色: # 404040;} .对话。关闭{宽度:20像素高度:20 px余量:3px右浮动:光标:指针指针;}/style/head body inputtype=' button ' value=' Dialog Test ' onclick=' openDialog();'/divided=' DLG测试' class=' Dialog ' img class=' close ' alt=' src=' http : images/close。png ' div class=' title ' Dialog/div div class=' content '/div/div脚本类型=' text/JavaScript '函数Dialog(id){ this。id=id变量=这个;document.getElementById(id).儿童[0]。onclick=function(){ that。close();} }对话框。原型。show=function(){ var DLG=document。getelementbyid(这。id);DLG。风格。display=' blockdlg=null}对话框。原型。关闭=函数(){ var DLG=文档。getelementbyid(这。id);DLG。风格。display=" noneDLG=null }/脚本类型=' text/JavaScript '函数openDialog(){ var DLG=new Dialog(' DLG测试');DLG。show();}/脚本/正文超文本标记语言这样在点击按钮的时候就可以弹出对话,点击关闭按钮的时候隐藏对话,看起来不错实现了需求,但总感觉缺点儿什么,一般对话显示的时候页面还会弹出一层灰蒙蒙半透明的罩子,阻止页面其它地方的点击,对话框隐藏的时候罩子去掉,页面又能够操作。加些代码添个罩子。在身体顶部添加一个封面div id='封面' class='封面'/div为其添加风格复制代码代码如下:封面{宽度:100%;高度:100%;位置:绝对;z索引:10;背景色: # 666;opa city 33600.5 display : none }为了打开的时候显示封面,需要修改openDialog方法复制代码代码如下:函数openDialog(){ var DLG=new Dialog(' DLG测试');文件。getelementbyid('封面')。风格。display=' blockDLG。show();}

效果非常好。对话框弹出后,灰色半透明的封面覆盖了页面上的按钮,对话框位于其上方。这时,问题来了。当对话框关闭时,封面仍在。没有代码可以隐藏它。查看打开时如何显示封面,关闭时如何隐藏!不完全是。打开的代码是由页面按钮的事件处理程序定义的,在其中添加显示页面封面的方法是合理的。但是,关闭对话框的方法是对话框控件的逻辑(虽然很简单,远不是控件),与页面无关。修改对话框的关闭方式可以吗?甚至没有!原因有二。首先,Dialog在定义时并不知道页面封面的存在,这两个控件之间没有耦合关系。如果隐藏的封面逻辑写在dialog的close方法中,dialog依赖于封面,这意味着如果页面上没有封面,Dialog就会出错。另外,在定义Dialog时,它并不知道特定页面的封面id,也没有办法知道要隐藏哪个div。构建Dialog时传入封面id可以吗?这样,两个控件之间就不存在依赖关系,可以通过id找到页面封面DIV。但是,如果用户的某些页面需要弹出页面封面,如果有些用户不需要,该怎么办?是时候充分发挥这个事件了。修改对话框对象,复制openDialog方法的代码如下:函数对话框(ID) {this。ID=IDthis.close _ handler=null变量=这个;document.getElementById(id)。儿童[0]。onclick=function(){ that . close();if(type of that . close _ handler==' function '){ that . close _ handler();}}}复制的代码如下:函数open dialog(){ var DLG=new dialog(' DLG test ');document . getelementbyid(' page cover '). style . display=' block ';DLG . close _ handler=function(){ document . getelementbyid(' page cover '). style . display=' none ';} DLG . show();}在Dialog对象内部添加一个句柄,close按钮的click事件处理程序在调用close方法后判断该句柄是否为函数,如果是,则调用并执行该句柄。在openDialog方法中,句柄在Dialog对象创建后被分配为隐藏的页面覆盖方法,这样当Dialog关闭时页面覆盖被隐藏,不会导致两个控件之间的耦合。这个交互过程是定义事件——并绑定事件处理程序——以触发事件的简单过程。DOM对象的事件,比如按钮的点击事件,原则上是相似的。上面给出的高级定制事件的小例子非常简单,远不如DOM本身的事件详细。这种简单的事件处理有很多缺点。1.没有共性。如果您正在定义一个控件,您必须编写一组类似的结构。2.事件绑定是独占的。只能绑定一个close事件处理程序,绑定新的事件处理程序将覆盖以前的绑定。3.包装不完美。

如果用户不知道close_handler有句柄,就没有办法绑定事件,只能查看源代码,逐一分析这些弊端。缺点一旦熟悉,用过面向对象的同学很容易想到解决方案——继承;对于第二个缺点,可以提供一个容器(二维数组)以统一的方式管理所有事件。缺点需要解决,缺点需要结合。在自定义事件管理对象中增加统一接口,用于添加/删除/触发事件复制。代码如下:函数事件目标(){this。处理程序={ };} event target . prototype={ constructor : event target,addHandler:function(类型,处理程序){ if(type of this . handlers[type]=' undefined '){ this . handlers[type]=new Array();} this.handlers[type]。push(处理程序);},removeHandler:function(类型,处理程序){ if(this . handlers[type]instance of Array){ var handlers=this . handlers[type];for(var i=0,len=handlers.length伊琳;I){ if(handler[I]==handler){ handler . splice(I,1);打破;} } } },trigger:function(event){ if(!event . target){ event . target=this;} if(this . handlers[event . type]instance of Array){ var handlers=this . handlers[event . type];for(var i=0,len=handlers.length伊琳;i ){ handlers[i](事件);}}} }addHandler方法用于添加事件处理程序,removeHandler方法用于移除事件处理程序,所有事件处理程序都在属性Handler中存储和管理。调用trigger方法来触发一个事件,该事件接收一个至少包含type属性作为参数的对象,当被触发时,它将在handlers属性中找到与该类型对应的事件处理程序。写一段代码来测试它。

复制代码代码如下:函数OnClose(事件){ alert(' message : '事件。消息);} var target=新事件target();target.addHandler('close ',onClose);//浏览器不能帮我们创建事件对象了,自己创建一个定义变量事件={ type: "关闭”,消息:封皮关闭!"};target.trigger(事件);至此后连个弊端一解决,应用一下继承解决第一个弊端,下面是寄生式组合继承的核心代码,这种继承方式是目前公认的Java脚本语言最佳继承方式复制代码代码如下:函数extend(subType,SuperType){ var prototype=Object(SuperType。原型);prototype . constructor=subtypesubtype . prototype=prototype }最后写成的版本就是这样的复制代码代码如下:DOCTYPE html html标题标题测试/标题样式类型=' text/CSS ' html,正文{ height :100%;宽度:100%;划水:0;margin:0}。对话框{位置:固定宽度宽度:300像素高度:300 px前:50%;左侧:50%;边距-top :-200 px;边距-左侧:-200像素;盒影:2 px 2px 4px # CCC背景-color : # f1 f1;z索引:30;display:none}。对话标题{ font-size :16 px字体粗细:加粗;color: # fffpadding:4px背景色: # 404040;} .对话。关闭{宽度:20像素高度:20 px余量:3px右浮动:光标:指针指针;} .封面{宽度:100%;高度:100%;位置:绝对;z索引:10;背景色: # 666;opa city 33600.5 display : none }/style/head body div id=' page cover ' class=' page cover '/div输入类型=' button '值=' Dialog Test ' onclick=' openDialog();'/div id=' DLG测试' class=' dialog ' img class=' close ' alt=' src=' http : images/close。png ' div class=' title '对话框/div class=' content '/div/div脚本类型='text/javascript '函数事件目标(){ this。处理程序={ };}活动目标。prototype={ constructor :事件目标,addHandler:function(类型,处理程序){ if(这种类型。处理程序[type]=' undefined '){ this。处理程序[类型]=新数组();} this.handlers[type].推送(处理程序);},removeHandler:function(类型,处理程序){如果(这个。处理程序[类型]数组的实例){ var handlers=this。处理程序[类型];for(var i=0,len=handlers.length伊琳;I){ if(handler[I]==handler){ handler。拼接(,1);打破;} } } },trigger:function(event){ if(!事件。target){ event。目标=这个;}如果(这个。处理程序[事件。数组的类型]实例){ var handlers=this。处理程序[事件。type];for(var i=0,len=handlers.length伊琳;i ){ handlers[i](事件);} } } }/script脚本类型=' text/JavaScript '函数扩展(子类型,超类型){ var prototype=Object(超类型。原型);prototype . constructor=subtypesubtype . prototype=prototype }/script脚本类型='text/javascript '函数对话框(id){事件目标。称这个为。id=id变量=这个;document.getElementById(id).儿童[0]。onclick=function(){ that。close();} }扩展(对话框,事件目标);对话。原型。show=function(){ var DLG=document。getelementbyid(这。id);DLG。风格。display=' blockdlg=null}对话框。原型。关闭=函数(){ var DLG=文档。getelementbyid(这。id);DLG。风格。display=" nonedlg=nullthis。触发器({ type : ' close ' });}/脚本脚本类型='text/javascript '函数openDialog(){ var DLG=new Dialog(' DLG测试');dlg.addHandler('close ',function(){ document。getelementbyid('封面')。风格。显示='无';});文件。getelementbyid('封面')。风格。display=' blockDLG。show();} /script /bodyhtml最后这样解决了几个弊端看起来就完美多了,其实可以把打开对话显示封面也写成类似关闭时事件的方式了。当代码中存在多个部分在特定时刻相互交互的情况下,自定义事件就非常有用了。如果每个对象都有其它对象的引用,那么整个代码高度耦合,对象改动会影响其它对象,维护起来困难重重。自定义事件使对象解耦,功能隔绝,这样对象之间实现了高聚合。

版权声明:JavaScript自定义事件介绍是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。