解决FireFox下[使用event很麻烦]的问题


Posted in Javascript onNovember 26, 2006

在FireFox下编写事件处理函数是很麻烦的事.
因为FireFox并没有 window.event . 如果要得到 event 对象,就必须要声明时间处理函数的第一个参数为event.

所以为了兼容IE与FireFox,一般的事件处理方法为:
btn.onclick=handle_btn_click;
function handle_btn_click(evt)
{
    if(evt==null)evt=window.event;//IE
    //处理事件.
}
对于简单的程序,这不算麻烦.

但对于一些复杂的程序,某写函数根本就不是直接与事件挂钩的.如果要把event传进该参数,那么所有的方法都要把event传来传去..这简直就是噩梦.

下面介绍一个解决这个麻烦事的方法,与原理.

JScript中,函数的调用是有一个 func.caller 这个属性的.
例如 
function A()
{
    B();
}
function B()
{
    alert(B.caller);
}
如果B被A调用,那么B.caller就是A

另外,函数有一个arguments属性. 这个属性可以遍历函数当前执行的参数:
function myalert()
{
    var arr=[];
    for(var i=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;
function handle_click()
{
    showcontent();
}
function showcontent()
{
    var evt=SearchEvent();
    if(evt&&evt.shiftKey)//如果是基于事件的调用,并且shift被按下
        window.open(global_helpurl);
    else
        location.href=global_helpurl;
}
function SearchEvent()
{
    func=SearchEvent.caller;
    while(func!=null)
    {
        var arg0=func.arguments[0];
        if(arg0)
        {
            if(arg0.constructor==Event) // 如果就是event 对象
                return arg0;
        }
        func=func.caller;
    }
    return null;
}
这个例子使用了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();
}
function FixPrototypeForGecko()
{
    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);
}
function element_prototype_get_runtimeStyle()
{
    //return style instead...
    return this.style;
}
function window_prototype_get_event()
{
    return SearchEvent();
}
function event_prototype_get_srcElement()
{
    return this.target;
}

function SearchEvent()
{
    //IE
    if(document.all)
        return window.event;

    func=SearchEvent.caller;
    while(func!=null)
    {
        var arg0=func.arguments[0];
        if(arg0)
        {
            if(arg0.constructor==Event)
                return arg0;
        }
        func=func.caller;
    }
    return null;
}
</body></html>

Javascript 相关文章推荐
仅Firefox中链接A无法实现模拟点击以触发其默认行为
Jul 31 Javascript
JS 有趣的eval优化输入验证实例代码
Sep 22 Javascript
JavaScript的jQuery库插件的简要开发指南
Aug 12 Javascript
JS数组排序技巧汇总(冒泡、sort、快速、希尔等排序)
Nov 24 Javascript
微信小程序 实战程序简易新闻的制作
Jan 09 Javascript
详解VUE 对element-ui中的ElTableColumn扩展
Mar 28 Javascript
vue实现简单loading进度条
Jun 06 Javascript
解决vue中修改export default中脚本报一大堆错的问题
Aug 27 Javascript
JS实现的获取银行卡号归属地及银行卡类型操作示例
Jan 08 Javascript
图文详解vue框架安装步骤
Feb 12 Javascript
vue 项目build错误异常的解决方法
Apr 22 Javascript
通过实践编写优雅的JavaScript代码
May 30 Javascript
DHTML 中的绝对定位
Nov 26 #Javascript
js验证表单第二部分
Nov 25 #Javascript
js验证表单大全
Nov 25 #Javascript
禁止刷新,回退的JS
Nov 25 #Javascript
用函数式编程技术编写优美的 JavaScript
Nov 25 #Javascript
通过JAVASCRIPT读取ASP设定的COOKIE
Nov 24 #Javascript
键盘控制事件应用教程大全
Nov 24 #Javascript
You might like
php 抽象类的简单应用
2011/09/06 PHP
php递归获取目录内文件(包含子目录)封装类分享
2013/12/25 PHP
PHP MYSQL简易交互式站点开发
2016/12/27 PHP
Javascript 文件夹选择框的两种解决方案
2009/07/01 Javascript
js 使用form表单select类实现级联菜单效果
2012/12/19 Javascript
javascript操作css属性
2013/12/30 Javascript
从零学JSON之JSON数据结构
2014/05/19 Javascript
jQuery中队列queue()函数的实例教程
2016/05/03 Javascript
node.js 动态执行脚本
2016/06/02 Javascript
JS使用插件cryptojs进行加密解密数据实例
2017/05/11 Javascript
关于Angular2 + node接口调试的解决方案
2017/05/28 Javascript
浅析node应用的timing-attack安全漏洞
2018/02/28 Javascript
Node.js log4js日志管理详解
2018/07/31 Javascript
微信小程序wx:for循环的实例详解
2018/10/07 Javascript
Vue Cli3 创建项目的方法步骤
2018/10/15 Javascript
vue keep-alive 动态删除组件缓存的例子
2019/11/04 Javascript
Vue项目前后端联调(使用proxyTable实现跨域方式)
2020/07/18 Javascript
Python使用py2exe打包程序介绍
2014/11/20 Python
解决Python传递中文参数的问题
2015/08/04 Python
深入学习python的yield和generator
2016/03/10 Python
pytorch对梯度进行可视化进行梯度检查教程
2020/02/04 Python
利用css3-animation实现逐帧动画效果
2016/03/10 HTML / CSS
贝玲妃英国官网:Benefit英国
2018/02/03 全球购物
精选奢华:THE LIST
2019/09/05 全球购物
中医药大学市场营销专业自荐信
2013/09/29 职场文书
校园达人秀策划书
2014/01/12 职场文书
高三语文教学反思
2014/01/15 职场文书
幼儿教师工作感言
2014/02/14 职场文书
党员创先争优公开承诺书
2014/03/28 职场文书
党员干部三严三实心得体会
2014/10/13 职场文书
大学生求职简历自我评价
2015/03/02 职场文书
工作试用期自我评价
2015/03/10 职场文书
2015社区健康教育工作总结
2015/05/20 职场文书
学习雷锋主题班会
2015/08/14 职场文书
2019财务转正述职报告
2019/06/27 职场文书
PHP实现考试倒计时功能代码
2021/04/16 PHP