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


Posted in Javascript onAugust 22, 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 下的实现:

下面给出一个简单的代码.. 有兴趣的可以补充

<script>
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; 
}
</script>
</body></html>
Javascript 相关文章推荐
node.js中的fs.mkdirSync方法使用说明
Dec 17 Javascript
javascript 闭包详解
Feb 15 Javascript
jquery实现最简单的滑动菜单效果代码
Sep 12 Javascript
Bootstrap每天必学之栅格系统(布局)
Nov 25 Javascript
关于input全选反选恶心的异常情况
Jul 24 Javascript
js传递数组参数到后台controller的方法
Mar 29 Javascript
如何检查一个对象是否为空
Apr 11 Javascript
JS前端面试必备——基本排序算法原理与实现方法详解【插入/选择/归并/冒泡/快速排序】
Feb 24 Javascript
Vue父组件向子组件传值以及data和props的区别详解
Mar 02 Javascript
vue实现瀑布流组件滑动加载更多
Mar 10 Javascript
Vue+Openlayers自定义轨迹动画
Sep 24 Javascript
通过实例了解Render Props回调地狱解决方案
Nov 04 Javascript
Javascript客户端脚本的设计和应用
Aug 21 #Javascript
让iframe框架网页在任何浏览器下自动伸缩
Aug 18 #Javascript
去除链接虚线全面分析总结
Aug 15 #Javascript
静态的动态续篇之来点XML
Aug 15 #Javascript
实用javaScript技术-屏蔽类
Aug 15 #Javascript
巧妙破除网页右键禁用的十大绝招
Aug 12 #Javascript
总结一些js自定义的函数
Aug 05 #Javascript
You might like
ThinkPHP实现静态缓存和动态缓存示例代码
2017/05/02 PHP
常用简易JavaScript函数
2009/04/09 Javascript
JavaScript 申明函数的三种方法 每个函数就是一个对象(一)
2009/12/04 Javascript
JQuery开发的数独游戏代码
2010/10/29 Javascript
javascript 自定义回调函数示例代码
2014/09/26 Javascript
D3.js 从P元素的创建开始(显示可加载数据)
2014/10/30 Javascript
jQuery及JS实现循环中暂停的方法
2015/02/02 Javascript
jQuery插件datatables使用教程
2016/04/21 Javascript
jQuery动态改变多行文本框高度的方法
2016/09/07 Javascript
js获取地址栏中传递的参数(两种方法)
2017/02/08 Javascript
vue.js移动端tab组件的封装实践实例
2017/06/30 Javascript
Layui 设置select下拉框自动选中某项的方法
2018/08/14 Javascript
[59:48]LGD vs IG 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python EOL while scanning string literal问题解决方法
2020/09/18 Python
在Python下进行UDP网络编程的教程
2015/04/29 Python
使用python实现rsa算法代码
2016/02/17 Python
python使用SMTP发送qq或sina邮件
2017/10/21 Python
matplotlib简介,安装和简单实例代码
2017/12/26 Python
对Python生成器、装饰器、递归的使用详解
2019/07/19 Python
python 三元运算符使用解析
2019/09/16 Python
使用wxpy实现自动发送微信消息功能
2020/02/28 Python
python 实现在无序数组中找到中位数方法
2020/03/03 Python
python GUI库图形界面开发之PyQt5结合Qt Designer创建信号与槽的详细方法与实例
2020/03/08 Python
BabyBjörn婴儿背带法国官网:BabyBjorn法国
2018/06/16 全球购物
DNA基因检测和分析:23andMe
2019/05/01 全球购物
分别介绍一下Session Bean和Entity Bean
2015/03/13 面试题
如何从一个文件档案的尾端新增记录
2016/12/02 面试题
美工的岗位职责
2013/11/14 职场文书
年度献血先进个人事迹材料
2014/02/14 职场文书
政风行风自查自纠报告
2014/10/21 职场文书
2014年业务员工作总结范文
2014/11/17 职场文书
幼儿园大班教师个人工作总结
2015/02/05 职场文书
公司财务人员岗位职责
2015/04/14 职场文书
公司员工培训管理制度
2015/08/04 职场文书
好段摘抄大全(48句)
2019/08/08 职场文书
Python数据可视化之用Matplotlib绘制常用图形
2021/06/03 Python