在FireFox下编写事件处理函数是很麻烦的事.
因为FireFox并没有window.event.如果要得到event对象,就必须要声明时间处理函数的第一个参数为event.
所以为了兼容IE与FireFox,一般的事件处理方法为:
btn.onclick=handle_btn_click;
functionhandle_btn_click(evt)
{
if(evt==null)evt=window.event;//IE
//处理事件.
}
对于简单的程序,这不算麻烦.
但对于一些复杂的程序,某写函数根本就不是直接与事件挂钩的.如果要把event传进该参数,那么所有的方法都要把event传来传去..这简直就是噩梦.
下面介绍一个解决这个麻烦事的方法,与原理.
JScript中,函数的调用是有一个func.caller这个属性的.
例如
functionA()
{
B();
}
functionB()
{
alert(B.caller);
}
如果B被A调用,那么B.caller就是A
另外,函数有一个arguments属性.这个属性可以遍历函数当前执行的参数:
functionmyalert()
{
vararr=[];
for(vari=0;i
arr[i]=myalert.arguments[i];
alert(arr.join("-"));
}
alert("hello","world",1,2,3)
就能显示hello-world-1-2-3
(arguments的个数与调用方有关,而与函数的参数定义没有任何关系)
根据这两个属性,我们可以得到第一个函数的event对象:
btn.onclick=handle_click;
functionhandle_click()
{
showcontent();
}
functionshowcontent()
{
varevt=SearchEvent();
if(evt&&evt.shiftKey)//如果是基于事件的调用,并且shift被按下
window.open(global_helpurl);
else
location.href=global_helpurl;
}
functionSearchEvent()
{
func=SearchEvent.caller;
while(func!=null)
{
vararg0=func.arguments[0];
if(arg0)
{
if(arg0.constructor==Event)//如果就是event对象
returnarg0;
}
func=func.caller;
}
returnnull;
}
这个例子使用了SearchEvent来搜索event对象.其中'Event'是FireFox的event.constructor.
在该例子运行时,
SearchEvent.caller就是showcontent,但是showcontent.arguments[0]是空.所以func=func.caller时,func变为handle_click.
handle_click被FireFox调用,虽然没有定义参数,但是被调用时,第一个参数就是event,所以handle_click.arguments[0]就是event!
针对上面的知识,我们可以结合prototype.__defineGetter__来实现window.event在FireFox下的实现:
下面给出一个简单的代码..有兴趣的可以补充
if(window.addEventListener)
{
FixPrototypeForGecko();
}
functionFixPrototypeForGecko()
{
HTMLElement.prototype.__defineGetter__("runtimeStyle",element_prototype_get_runtimeStyle);
window.constructor.prototype.__defineGetter__("event",window_prototype_get_event);
Event.prototype.__defineGetter__("srcElement",event_prototype_get_srcElement);
}
functionelement_prototype_get_runtimeStyle()
{
//returnstyleinstead...
returnthis.style;
}
functionwindow_prototype_get_event()
{
returnSearchEvent();
}
functionevent_prototype_get_srcElement()
{
returnthis.target;
}
functionSearchEvent()
{
//IE
if(document.all)
returnwindow.event;
func=SearchEvent.caller;
while(func!=null)
{
vararg0=func.arguments[0];
if(arg0)
{
if(arg0.constructor==Event)
returnarg0;
}
func=func.caller;
}
returnnull;
}
</body></html>