zoukankan      html  css  js  c++  java
  • 解决FireFox下[使用event很麻烦]的问题


    在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>
  • 相关阅读:
    JavaCC 研究与应用( 8000字 心得 源程序)
    推荐UML插件Green UML、AmaterasUML
    Custom PMD Rules
    静态分析工具及使用总结(三)
    静态分析工具及使用总结(二)CheckStyle
    静态分析工具及使用总结(一)
    基于antlr的表达式解析器——函数类型验证
    基于antlr的表达式解析器——函数生成(通过freemarker)
    网络流--最大流--hlpp(预流推进)模板
    网络流--最大流--Dinic模板矩阵版(当前弧优化+非当前弧优化)
  • 原文地址:https://www.cnblogs.com/huqingyu/p/213083.html
Copyright © 2011-2022 走看看