平时我们获取事件对象一般写法如下:

function getEvent(event) {
    return event || window.event  // IE:window.event
}

如果没有参数,也可写成(非IE :事件对象会自动传递给对应的事件处理函数,且为第一个参数):

function getEvent() {
    return arguments[0] || window.event // IE:window.event
}

这样的写法在除 Firefox(测试版本:3.0.12,下同) 外的浏览器上运行都不会有问题,但 Firefox 为什么例外呢?让我们这样一种情形:

<button id="btn" onclick="foo()">按钮</button>

<script>
function foo(){
   var e =  getEvent();
   alert(e);
}
</script>

运行结果在 Firefox 中是 undefined,为什么呢?

在 Firefox 中调用其实是这样的,先调用执行的是:

function onclick(event) {
    foo();
}

然后调用执行的是:

function foo(){
   var e =  getEvent();
   alert(e);
}

会发现在 Firefox 下 onclick="foo()" 中的 foo() 无法自动传入事件对象参数,而默认传递给了系统生成的 onclick 函数,那本例我们可以通过 getEvent.caller.caller.arguments[0] 获得事件对象。

因此,我们的 getEvent 可以优化成(参照 yui_2.7.0b 中的 event/event-debug.js 中 getEvent 方法):

function getEvent(event) {
    var ev = event || window.event;

    if (!ev) {
        var c = this.getEvent.caller;
        while (c) {
            ev = c.arguments[0];
            if (ev && (Event == ev.constructor || MouseEvent  == ev.constructor)) { //怿飞注:YUI 源码 BUG,ev.constructor 也可能是 MouseEvent,不一定是 Event
                break;
            }
            c = c.caller;
        }
    }

    return ev;
}

当然还有一个很简单的解决方法,就是手动将参数传递给 onclick="foo()"

<button id="btn" onclick="foo(event)">按钮</button>


共有18 条评论

  1. 1. 头像 stefyang

    为什么传给onclick的参数是event,而不是ev或者其他名字的事件对象呢
    原来一直认为onclick=”foo();”;是如下的两步
    element.onclick= new Function(‘foo();’);
    element.addlistener(‘click’,this.onclick,this);
    不知道理解的是否正确

  2. 2. 头像 cssrain

    一般都是直接传递event,这种使用第一个参数的方法没用过。
    学习了。

  3. 3. 头像 Shawphy

    在 Firefox 中调用其实是这样的,先调用执行的是:
    然后调用执行的是:

    这两段代码似乎放反了,逻辑上不通。

  4. 4. 头像 怿飞

    @Shawphy 是写反了,sorry

  5. 5. 头像 vapour

    终于又见到怿飞的文章了,期待下一篇

  6. 6. 头像 cc

    我也想知道为什么
    onclick=”foo(event)”
    这里是event

  7. 7. 头像 访客

    博主,请问你用的是哪个代码高亮插件?告诉下名字就好了,我自己搜索去,谢谢!!!

  8. 8. 头像 天堂左我往右

    终于又见怿飞兄的新文章了…顶

  9. 9. 头像 netwjx

    onclick=’alert(event)’
    看看喽,或者是jquery
    $(‘a’).click(function(){alert(arguments[0])});

  10. 10. 头像 Ronecy

    很遇到这种情况。

    了解一下。

  11. 11. 头像 怿飞

    @cc 因为Firefox下默认给出的就是event,就如这个函数:

    function onclick(event) {
    foo();
    }

  12. 12. 头像 怿飞

    @访客 用的是google code prettify,详细见:http://code.google.com/p/google-code-prettify/

  13. 13. 头像 cc

    那这个事w3c的标准吗

  14. 14. 头像 访客

    非常感谢告知插件名称!!!

  15. 15. 头像 Kelvin

    受教!3Q!

  16. 16. 头像 骨头

    不懂JAVA

  17. 17. 头像 wuyi's blog

    写的很全面,建议从用户角度着想,不要太长。

  18. 18. 头像 dongyuwei

    按钮 传递this就完全ok了。

发表评论

(必填)

(必填,会为您保密)

评论仅支持“a、abbr、strong、em、blockquote、code”几个简单的标签