javascript事件驱动模型的不完全剖析
2008-02-23 07:43:00来源:互联网 阅读 ()
当然这里指的事件驱动并不是指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");
this.label2 = page.document.getElementById("label2");
this.label3 = page.document.getElementById("label3");
//EventHandlers 事件处理函数
ControlDemo.prototype.PageLoad = function(sender,event)
{
this.page.defaultStatus = "事件驱动框架演示~~";
this.page.resizeTo(600,400);
}
ControlDemo.prototype.Button1_Click = function(sender,event)
{
alert("Hello ^_^");
}
ControlDemo.prototype.Button2_Click = function(sender,event)
{
if (page.opener == null)
{
page.opener = page;
}
page.close();
}
ControlDemo.prototype.Textbox1_KeyUp = function(sender, event)
{
this.keyPressed ;
this.label1.innerText = this.keyPressed;
this.label2.innerText = this.textbox1.value.length;
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash