跨浏览器事件处理

时间:2010-08-25 17:46:17

标签: javascript events cross-browser addeventlistener attachevent

我需要一个跨浏览器函数来注册事件处理程序和(大多数)一致的处理程序体验。我不需要像jQuery这样的库的全部重量或功能,所以我写了自己的。我相信我已经用下面的代码完成了我的目标,到目前为止我的测试已经成功,但我已经盯着它看了太久。我的逻辑或陷阱中是否有任何我缺失的缺陷?

编辑1:为了清晰起见,每个块都有浏览器意图。更新了IE块,不立即调用func(感谢Andy E's keen eyes)。

编辑2:更新了IE块,使用func.call()而不是this来呼叫elem

编辑3:已更新,以便通过“好零件”传递JSLint

function hookEvent(elem, evt, func)
{
    if (typeof elem === "string")
    {
        elem = document.getElementById(elem);
    }
    if (!elem)
    {
        return null;
    }
    var old, r;
    if (elem.addEventListener)  //w3c
    {
        elem.addEventListener(evt, func, false);
        r = true;
    }
    else if (elem.attachEvent)  //ie
    {
        elem[evt + func] = function ()
        {
            func.call(this, window.event);
        };
        r = elem.attachEvent("on" + evt, elem[evt + func]);
    }
    else                        //old
    {
        old = elem["on" + evt] ? elem["on" + evt] : function (e) { };
        elem["on" + evt] = function (e)
        {
            if (!e)
            {
                e = window.event;
            }
            old.call(this, e);
            func.call(this, e);
        };
        r = true;
    }
    return r;
}

1 个答案:

答案 0 :(得分:3)

这一行存在问题:

r = elem.attachEvent("on" + evt, func.call(elem, window.event));

这将立即执行 func(),而不是将其作为事件的处理程序附加。相反, func()的返回值将分配给事件,如果事件的类型不是"function",则会抛出错误。

我可以理解您不想使用框架,但许多(很多)其他人编写了跨浏览器事件处理代码段。 John Resig有一个版本,谷歌用于“javascript addEvent”等等。

http://www.google.com/search?q=javascript+addevent