解决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 相关文章推荐
javascript代码编写需要注意的7个小细节小结
Sep 21 Javascript
javascript 进阶篇2 CSS XML学习
Mar 14 Javascript
表单类各种类型(文本框)失去焦点效果jquery代码
Apr 26 Javascript
Jquery 模板数据绑定插件的使用方法详解
Jul 08 Javascript
JQuery右键菜单插件ContextMenu使用指南
Dec 19 Javascript
js 动态添加元素(div、li、img等)及设置属性的方法
Jul 19 Javascript
jQuery日程管理插件fullcalendar使用详解
Jan 07 Javascript
将 vue 生成的 js 上传到七牛的实例
Jul 28 Javascript
详解解决Vue相同路由参数不同不会刷新的问题
Oct 12 Javascript
node之本地服务器图片上传的方法示例
Mar 26 Javascript
微信小程序自定义波浪组件使用方法详解
Sep 21 Javascript
Vue 技巧之控制父类的 slot
Feb 24 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
简单介绍win7下搭建apache+php+mysql开发环境
2015/08/06 PHP
使用phpstorm和xdebug实现远程调试的方法
2015/12/29 PHP
PHP 生成微信红包代码简单
2016/03/25 PHP
PHP设计模式之工厂模式(Factory Pattern)的讲解
2019/03/21 PHP
共享自己写一个框架DreamScript
2007/01/20 Javascript
Document 对象的常用方法
2009/07/31 Javascript
Javascript String.replace的妙用
2009/09/08 Javascript
JavaScript位移运算符(无符号) &gt;&gt;&gt; 三个大于号 的使用方法详解
2016/03/31 Javascript
jQuery通用的全局遍历方法$.each()用法实例
2016/07/04 Javascript
js replace(a,b)之替换字符串中所有指定字符的方法
2016/08/17 Javascript
jquery实现静态搜索功能(可输入搜索文字)
2017/03/28 jQuery
详述 Sublime Text 打开 GBK 格式中文乱码的解决方法
2017/10/26 Javascript
JavaScript数组push方法使用注意事项
2017/10/30 Javascript
在react-router4中进行代码拆分的方法(基于webpack)
2018/03/08 Javascript
vue项目中vue-i18n和element-ui国际化开发实现过程
2018/04/25 Javascript
vue ssr 实现方式(学习笔记)
2019/01/18 Javascript
JavaScript私有变量实例详解
2019/01/24 Javascript
在vue中使用setInterval的方法示例
2019/04/16 Javascript
layui问题之模拟table表格中的选中按钮选中事件的方法
2019/09/20 Javascript
解决layer.confirm快速点击会重复触发事件的问题
2019/09/23 Javascript
Python简单连接MongoDB数据库的方法
2016/03/15 Python
python中判断文件编码的chardet(实例讲解)
2017/12/21 Python
Python+Django搭建自己的blog网站
2018/03/13 Python
java中的控制结构(if,循环)详解
2019/06/26 Python
Python openpyxl模块原理及用法解析
2020/01/19 Python
python 在右键菜单中加入复制目标文件的有效存放路径(单斜杠或者双反斜杠)
2020/04/08 Python
Keras使用ImageNet上预训练的模型方式
2020/05/23 Python
python 可视化库PyG2Plot的使用
2021/01/21 Python
canvas实现图片马赛克的示例代码
2018/03/26 HTML / CSS
澳大利亚百货公司:David Jones
2018/02/08 全球购物
自动化职业生涯规划书范文
2014/01/03 职场文书
保护环境建议书300字
2014/05/13 职场文书
关于倡议书的范文
2015/04/29 职场文书
幼儿园教师心得体会范文
2016/01/21 职场文书
Python学习开发之图形用户界面详解
2021/08/23 Python
Mysql中的触发器定义及语法介绍
2022/06/25 MySQL