解决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 相关文章推荐
jQuery对象和DOM对象相互转化
Apr 24 Javascript
javascript KeyDown、KeyPress和KeyUp事件的区别与联系
Dec 03 Javascript
含有CKEditor的表单如何提交
Jan 09 Javascript
js 判断控件获得焦点的示例代码
Mar 04 Javascript
JS父页面与子页面相互传值方法
Mar 05 Javascript
javascript字母大小写转换的4个函数详解
May 09 Javascript
jQuery中triggerHandler()方法用法实例
Jan 19 Javascript
js显示动态时间的方法详解
Aug 20 Javascript
详解Vue 动态添加模板的几种方法
Apr 25 Javascript
MVVM框架下实现分页功能示例
Jun 14 Javascript
vue+elementUI 复杂表单的验证、数据提交方案问题
Jun 24 Javascript
vue中data改变后让视图同步更新的方法
Mar 29 Vue.js
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中理解print EOT分界符和echo EOT的用法区别小结
2010/02/21 PHP
php实现遍历多维数组的方法
2015/11/25 PHP
Laravel实现构造函数自动依赖注入的方法
2016/03/16 PHP
PHP实现小偷程序实例
2016/10/31 PHP
PHP基于array_unique实现二维数组去重
2020/07/14 PHP
代码生成器 document.write()
2007/04/15 Javascript
JQuery 常用方法基础教程
2009/02/06 Javascript
script标签属性type与language使用选择
2012/12/02 Javascript
jquery实现无刷新验证码的简单实例
2016/05/19 Javascript
js控住DOM实现发布微博效果
2016/08/30 Javascript
如何学JavaScript?前辈的经验之谈
2016/12/28 Javascript
vue综合组件间的通信详解
2017/11/06 Javascript
Vue2.0 slot分发内容与props验证的方法
2017/12/12 Javascript
使用ngrok+express解决本地环境中微信接口调试问题
2018/02/26 Javascript
利用nodeJs anywhere搭建本地服务器环境的方法
2018/05/12 NodeJs
JavaScript引用类型Array实例分析
2018/07/24 Javascript
微信小程序缓存支持二次开发封装实现解析
2019/12/16 Javascript
[01:15:56]2018DOTA2亚洲邀请赛3月30日 小组赛A组 TNC VS Newbee
2018/03/31 DOTA
python使用心得之获得github代码库列表
2014/06/25 Python
python输出指定月份日历的方法
2015/04/23 Python
python shell根据ip获取主机名代码示例
2017/11/25 Python
pandas 选择某几列的方法
2018/07/03 Python
python多进程并发demo实例解析
2019/12/13 Python
Python如何使用OS模块调用cmd
2020/02/27 Python
Python利用for循环打印星号三角形的案例
2020/04/12 Python
python+selenium实现12306模拟登录的步骤
2021/01/21 Python
诺心蛋糕官网:LE CAKE
2018/08/25 全球购物
招商业务员岗位职责
2013/12/16 职场文书
房地产销售计划书
2014/01/10 职场文书
英文求职信写作小建议
2014/02/16 职场文书
有多年工作经验的自我评价
2014/03/02 职场文书
2014年党的群众路线教育实践活动总结
2014/04/25 职场文书
经济贸易专业自荐信
2014/06/11 职场文书
2015社区六五普法工作总结
2015/04/21 职场文书
2015年艾滋病防治工作总结
2015/05/22 职场文书
python cv2图像质量压缩的算法示例
2021/06/04 Python