解决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实现查找数组中最大值方法汇总
Feb 13 Javascript
JS/jQ实现免费获取手机验证码倒计时效果
Jun 13 Javascript
jQuery实现节点的追加、替换、删除、复制功能示例
Jul 11 jQuery
2种简单的js倒计时方式
Oct 20 Javascript
jQuery实现checkbox全选功能完整实例
Jul 12 jQuery
Nuxt.js之自动路由原理的实现方法
Nov 21 Javascript
jQuery利用FormData上传文件实现批量上传
Dec 04 jQuery
vue返回上一页面时回到原先滚动的位置的方法
Dec 20 Javascript
vue以组件或者插件的形式实现throttle或者debounce
May 22 Javascript
jQuery实现小火箭返回顶部特效
Feb 03 jQuery
基于Vue.js+Nuxt开发自定义弹出层组件
Oct 09 Javascript
vue中 this.$set的使用详解
Nov 17 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
第六节 访问属性和方法 [6]
2006/10/09 PHP
php的crc32函数使用时需要注意的问题(不然就是坑)
2015/04/21 PHP
Linux(CentOS)下PHP扩展PDO编译安装的方法
2016/04/07 PHP
分享PHP-pcntl 实现多进程代码
2016/09/30 PHP
[原创]php集成安装包wampserver修改密码后phpmyadmin无法登陆的解决方法
2016/11/23 PHP
jQuery的运行机制和设计理念分析
2011/04/05 Javascript
js获取php变量的实现代码
2013/08/10 Javascript
div模拟滚动条效果示例代码
2013/10/16 Javascript
jquery对单选框,多选框,文本框等常见操作小结
2014/01/08 Javascript
jquery和雅虎的yql服务实现天气预报服务示例
2014/02/08 Javascript
JavaScript实现获得所有兄弟节点的方法
2015/07/23 Javascript
JavaScript+canvas实现七色板效果实例
2016/02/18 Javascript
javascript 实现文本使用省略号替代(超出固定高度的情况)
2017/02/21 Javascript
浅谈js for循环输出i为同一值的问题
2017/03/01 Javascript
Node.js数据库操作之连接MySQL数据库(一)
2017/03/04 Javascript
Kotlin学习第一步 kotlin语法特性
2017/05/25 Javascript
5分钟打造简易高效的webpack常用配置
2017/07/04 Javascript
JavaScript学习总结(一) ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)
2018/01/07 Javascript
JavaScript事件冒泡与事件捕获实例分析
2018/08/01 Javascript
JS/HTML5游戏常用算法之碰撞检测 像素检测算法实例详解
2018/12/12 Javascript
elementUI Tree 树形控件的官方使用文档
2019/04/25 Javascript
javascrpt密码强度校验函数详解
2020/03/18 Javascript
python单线程实现多个定时器示例
2014/03/30 Python
windows环境下tensorflow安装过程详解
2018/03/30 Python
对python3 一组数值的归一化处理方法详解
2018/07/11 Python
Numpy中的mask的使用
2018/07/21 Python
对Python3中dict.keys()转换成list类型的方法详解
2019/02/03 Python
python第三方库学习笔记
2020/02/07 Python
解决Python 写文件报错TypeError的问题
2020/10/23 Python
销售人员自我评价
2014/02/01 职场文书
商场租赁意向书
2014/07/30 职场文书
2014优秀党员事迹材料
2014/08/14 职场文书
小学班主任个人总结
2015/03/03 职场文书
财政局个人总结
2015/03/04 职场文书
求职简历自我评价2015
2015/03/10 职场文书
python-for x in range的用法(注意要点、细节)
2021/05/10 Python