javascript事件驱动模型的不完全剖析
由于javascript并不是真正意义上“面向对象”的语言,所以,在实现事件驱动模型的时候,总是会遇到一些困难。
当然这里指的事件驱动并不是指javascript固有的事件处理机制或者DOM的事件模型,而是指类似C#或者Java的那种事件模型。 javascript在处理事件驱动的时候最大的问题在于"this指针"困惑。 例如:<input type="button" onclick=function(){alert(this.value);} value="Hello World!"/> 这里的this指针毫无疑问是没有问题的 但是,<input type="button" id="button1"/> var objBtn = document.getElementById("button1"); objBtn.attachEvent('onclick', EventHandler); function EventHandler() { alert(this.value); } 运行这个脚本很吃惊地发现得到的是完全错误的结果 因为这里的this并不是objBtn这个input对象!而是全局的window对象! 类似的问题在javascript中还会经常出现 再比如一个更复杂的应用: function mainForm(form) { this.form = form; this.button1 = form.buttonOK; this.button2 = form.buttonCancel; this.button1.onclick = Button1_Click; //为按钮注册单击事件 this.button2.onclick = Button2_Click; mainForm.prototype. Button1_Click = function() { alert(this.button1.value); } mainForm.prototype.Button2_Click = function() { this.form.style.display = 'none'; } } 本来一段挺“漂亮”的代码,却不能正确运行,为什么呢?原来问题还是在this上,button1_Clicked和button2_Clicked两个函数虽然是mainForm类的成员函数,但是他们是被this.button1.onclick和this.button2.onclick调用(不完全准确的说法)的,所以函数中的this指得是button1和button2两个对象!这很令人困扰,不是吗? 为了解决这个问题,必须要保证函数调用者是mainForm对象而不是button或者其他的什么成员,为此,我思考出一种事件注册的机制,把上面的代码写成: this.button1.ClickEventSender = this; this.button1.onclick = function(){this.ClickEventSender.Button1_Click(this.ClickEventSender,self.event);} mainForm.prototype.Button1_Click = function(object, sender) { alert(this.button1.value); } 就得到了正确结果。 于是,一种完全的基于“后台代码”的“事件驱动”模型慢慢成型,下面是一段简短的Demo代码: //后台代码 //事件驱动框架(演示) //2004-11-16 Created //2004-11-17 Modified //ControlDemo.js function ControlDemo(page) { //初始化Page if (page == null) { page = self; } if (page != self) { //Do sth. here... } this.page = page; //Properties this.keyPressed = 0; //Controlable Entities //PageBody 注册PageLoad事件 this.body1 = page.document.getElementById("main"); this.page.PageLoadEventSender = this; this.body1.onload = function(){this.PageLoadEventSender.PageLoad(this.PageLoadEventSender,page.event);} //Button1 注册Click事件 this.button1 = page.button1; this.button1.value = "确定"; this.button1.ClickEventSender = this; this.button1.onclick = function(){this.ClickEventSender.Button1_Click(this.ClickEventSender,page.event);} //Button2 注册Click事件 this.button2 = page.button2; this.button2.value = "取消"; this.button2.ClickEventSender = this; this.button2.onclick = function(){this.ClickEventSender.Button2_Click(this.ClickEventSender,page.event);} //Textbox1 注册KeyUp、MouseMove事件 this.textbox1 = page.textbox1; this.textbox1.style.width = "100%"; this.textbox1.rows = 10; this.textbox1.KeyUpSender = this; this.textbox1.onkeyup = function(){this.KeyUpSender.Textbox1_KeyUp(this.KeyUpSender,page.event);} this.textbox1.MouseMoveSender = this; this.textbox1.onmousemove = function(){this.MouseMoveSender.Textbox1_MouseMove(this.MouseMoveSender, page.event);} //Labels this.label1 = page.document.getElementById("label1"); 上一篇: javascript实现函数重载的深入探索 下一篇: Javascript图片播放类ImageSlide.iclass.js 更多相关文章
|
推荐文章
· 制作会移动的文字
精彩文章
|