解决 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 相关文章推荐
JavaScript 解析Json字符串的性能比较分析代码
Dec 16 Javascript
jQuery源码分析之Callbacks详解
Mar 13 Javascript
AngularJS 基础ng-class-even指令用法
Aug 01 Javascript
jQuery ajax MD5实现用户注册即时验证功能
Oct 11 Javascript
js实现可输入可选择的select下拉框
Dec 21 Javascript
轻松理解JavaScript之AJAX
Mar 15 Javascript
浅谈Vue-cli 命令行工具分析
Nov 22 Javascript
React从react-router路由上做登陆验证控制的方法
May 10 Javascript
详解wepy开发小程序踩过的坑(小结)
May 22 Javascript
js图片无缝滚动插件使用详解
May 26 Javascript
Vue-Cli项目优化操作的实现
Oct 27 Javascript
js实现星星海特效的示例
Sep 28 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实例分享之mysql数据备份
2014/05/19 PHP
Yii框架在页面输出执行sql语句以方便调试的实现方法
2014/12/24 PHP
php上传图片并压缩的实现方法
2015/12/22 PHP
PHP对象链式操作实现原理分析
2016/10/09 PHP
Zend Framework分发器用法示例
2016/12/11 PHP
PHP下载远程图片的几种方法总结
2017/04/07 PHP
学习jquery之一
2007/04/27 Javascript
JavaScript获取页面上某个元素的代码
2011/03/13 Javascript
js实现浮动在网页右侧的简洁QQ在线客服代码
2015/09/04 Javascript
纯JavaScript代码实现文本比较工具
2016/02/17 Javascript
JavaScript代码实现图片循环滚动效果
2020/03/19 Javascript
BootStrap Table 设置height表头与内容无法对齐的问题
2016/12/28 Javascript
基于JavaScript实现飘落星星特效
2017/08/10 Javascript
对vuejs的v-for遍历、v-bind动态改变值、v-if进行判断的实例讲解
2018/08/27 Javascript
vue-cli构建vue项目的步骤详解
2019/01/27 Javascript
vue项目中自定义video视频控制条的实现代码
2020/04/26 Javascript
ES6中的类(Class)示例详解
2020/12/09 Javascript
代码块高亮可复制显示js插件highlight.js+clipboard.js整合
2021/02/15 Javascript
[37:45]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS Orenda
2014/05/22 DOTA
Python数据类型学习笔记
2016/01/13 Python
Python 处理数据的实例详解
2017/08/10 Python
Python基于Matplotlib库简单绘制折线图的方法示例
2017/08/14 Python
Python3 获取一大段文本之间两个关键字之间的内容方法
2018/10/11 Python
python正则表达式匹配IP代码实例
2019/12/28 Python
Django model重写save方法及update踩坑详解
2020/07/27 Python
python 列表推导和生成器表达式的使用
2021/02/01 Python
详解css3 flex弹性盒自动铺满写法
2020/09/17 HTML / CSS
超级英雄、电影和电视、乐队和音乐T恤:Loud Clothing
2019/09/01 全球购物
Berghaus官网:户外服装和设备,防水服
2020/01/17 全球购物
某公司面试题
2012/03/05 面试题
What is EJB
2016/07/22 面试题
成人大专自我鉴定范文
2013/10/19 职场文书
上海世博会志愿者口号
2014/06/17 职场文书
就业意向协议书
2015/01/29 职场文书
my.ini优化mysql数据库性能的十个参数(推荐)
2021/05/26 MySQL
MySQL 主从复制数据不一致的解决方法
2022/03/18 MySQL