解决 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 相关文章推荐
js 实现无缝滚动 兼容IE和FF
Jul 15 Javascript
jQuery中filter()和find()的区别深入了解
Sep 25 Javascript
jquery转盘抽奖功能实现
Nov 13 Javascript
微信小程序 教程之模板
Oct 18 Javascript
javascript实现日期三级联动下拉框选择菜单
Dec 03 Javascript
JavaScript 上传文件(psd,压缩包等),图片,视频的实现方法
Jun 19 Javascript
一个简易时钟效果js实现代码
Mar 25 Javascript
AngularJS对动态增加的DOM实现ng-keyup事件示例
Mar 12 Javascript
Element-UI Table组件上添加列拖拽效果实现方法
Apr 14 Javascript
三步实现ionic3点击退出app程序
Sep 17 Javascript
webpack5 联邦模块介绍详解
Jul 08 Javascript
javascript前端实现多视频上传
Dec 13 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
PHP iconv 函数转gb2312的bug解决方法
2009/10/11 PHP
php函数重载的替代方法--伪重载详解
2015/05/08 PHP
Yii2如何批量添加数据
2016/05/17 PHP
php5.6.x到php7.0.x特性小结
2019/08/17 PHP
laravel 5.5 关闭token的3种实现方式
2019/10/24 PHP
JS实现日期加减的方法
2013/11/29 Javascript
jQuery在页面加载时动态修改图片尺寸的方法
2015/03/20 Javascript
javascript制作游戏开发碰撞检测的封装代码
2015/03/31 Javascript
用svg制作富有动态的tooltip
2015/07/17 Javascript
使用coffeescript编写node.js项目的方法汇总
2015/08/05 Javascript
JS中mouseover和mouseout多次触发问题如何解决
2016/06/06 Javascript
JavaScript检测原始值、引用值、属性
2016/06/20 Javascript
jQuery实现隔行变色的方法分析(对比原生JS)
2016/11/18 Javascript
Bootstrop实现多级下拉菜单功能
2016/11/24 Javascript
JavaScript实现公历转农历功能示例
2017/02/13 Javascript
基于vue配置axios的方法步骤
2017/11/09 Javascript
JavaScript类的继承方法小结【组合继承分析】
2018/07/11 Javascript
移动端滑动切换组件封装 vue-swiper-router实例详解
2018/11/25 Javascript
微信小程序使用wx.request请求服务器json数据并渲染到页面操作示例
2019/03/30 Javascript
JS解惑之Object中的key是有序的么
2019/05/06 Javascript
VueQuillEditor富文本上传图片(非base64)
2020/06/03 Javascript
[01:10]DOTA2次级职业联赛 - U5战队宣传片
2014/12/01 DOTA
[59:30]VG vs LGD 2019国际邀请赛淘汰赛 胜者组 BO3 第二场 8.22
2019/09/05 DOTA
Python的time模块中的常用方法整理
2015/06/18 Python
Python 爬虫学习笔记之单线程爬虫
2016/09/21 Python
python实现翻译word表格小程序
2020/02/27 Python
购买中国最好的电子产品:Geekbuying
2018/03/13 全球购物
Servlet方面面试题
2016/09/28 面试题
办公室文书岗位职责
2013/12/16 职场文书
庆八一活动方案
2014/01/25 职场文书
市三好学生主要事迹
2014/01/28 职场文书
企业2014年度工作总结
2014/12/10 职场文书
pycharm2021激活码使用教程(永久激活亲测可用)
2021/03/30 Python
golang正则之命名分组方式
2021/04/25 Golang
浅谈JS的二进制家族
2021/05/09 Javascript
解决flex布局中子项目尺寸不受flex-shrink限制
2022/05/11 HTML / CSS