【问题标题】:Correct usage of addEventListener() / attachEvent()?正确使用 addEventListener() / attachEvent()?
【发布时间】:2011-02-09 01:47:16
【问题描述】:

我想知道如何正确使用addEventListenerattachEvent

window.onload = function (myFunc1) { /* do something */ }

function myFunc2() { /* do something */ }

if (window.addEventListener) {
  window.addEventListener('load', myFunc2, false);
} else if (window.attachEvent) {
  window.attachEvent('onload', myFunc2);
}

 // ...

function myFunc1() { /* do something */ }

if (window.addEventListener) {
  window.addEventListener('load', myFunc1, false);
} else if (window.attachEvent) {
  window.attachEvent('onload', myFunc1);
}

function myFunc2() { /* do something */ }

if (window.addEventListener) {
  window.addEventListener('load', myFunc2, false);
} else if (window.attachEvent) {
  window.attachEvent('onload', myFunc2);
}

 // ...

?

这个跨浏览器是否安全,或者我应该更好地使用这样的东西:

function myFunc1(){ /* do something */ }
function myFunc2(){ /* do something */ }
// ...

function addOnloadEvent(fnc){
  if ( typeof window.addEventListener != "undefined" )
    window.addEventListener( "load", fnc, false );
  else if ( typeof window.attachEvent != "undefined" ) {
    window.attachEvent( "onload", fnc );
  }
  else {
    if ( window.onload != null ) {
      var oldOnload = window.onload;
      window.onload = function ( e ) {
        oldOnload( e );
        window[fnc]();
      };
    }
    else
      window.onload = fnc;
  }
}

addOnloadEvent(myFunc1);
addOnloadEvent(myFunc2);
// ...

AND:说myfunc2 仅适用于 IE 7。如何相应地修改正确/首选的方法?

【问题讨论】:

  • 你可能不喜欢我这样说,但你为什么不直接使用框架来处理这些问题呢?
  • 我会,但在这种情况下我不能。那么,你能帮我解决这个问题吗?
  • @ginny 看看我的回答。如果您需要任何进一步的解释,请告诉我。
  • 至少,您不应该每次都为要注册事件的事件模型进行测试。这可以很容易地分成一个通用函数,您可以将 elementevent typehandler 传递给该函数。

标签: javascript addeventlistener attachevent


【解决方案1】:

两者的用法相似,但两者的事件参数语法略有不同:

addEventListener (mdn reference):

所有主流浏览器(FF、Chrome、Edge)都支持

obj.addEventListener('click', callback, false);

function callback(){ /* do stuff */ }

Events listaddEventListener

attachEvent (msdn reference):

受 IE 5-8* 支持

obj.attachEvent('onclick', callback);

function callback(){ /* do stuff */ }

Events listattachEvent

参数

这两种方法的参数如下:

  1. 是事件类型。
  2. 是触发事件后调用的函数。
  3. (仅限addEventListener如果为真,则表示用户希望发起capture

说明

这两种方法都用于实现将事件附加到元素的相同目标。
不同之处在于attachEvent 只能用于较旧的trident 渲染引擎(IE5+ IE5-8*​​),而addEventListener 是在大多数其他浏览器中实现的 W3 标准(FF、Webkit、Opera、IE9+)。

对于可靠的跨浏览器事件支持,包括使用 Diaz 解决方案无法获得的规范化,请使用 framework

*IE9-10 支持这两种方法,以实现向后兼容性。

感谢Luke Puplett 指出attachEvent 已从IE11 中删除。

最小的跨浏览器实现

正如Smitty 建议的那样,您可以将这个Dustin Diaz addEvent 实现用于可靠的跨浏览器实现,而无需使用框架:

function addEvent(obj, type, fn) {
  if (obj.addEventListener) {
    obj.addEventListener(type, fn, false);
  }
  else if (obj.attachEvent) {
    obj["e"+type+fn] = fn;
    obj[type+fn] = function() {obj["e"+type+fn](window.event);}
    obj.attachEvent("on"+type, obj[type+fn]);
  }
  else {
    obj["on"+type] = obj["e"+type+fn];
  }
}

addEvent( document, 'click', function (e) {
  console.log( 'document click' )
})

【讨论】:

  • @CamiloMartin 如果您之后收到这样的评论,总是值得提出一个好的答案,谢谢:)
  • IE9+也支持addEventListener
  • attachEvent 已在 IE11 中删除,因此检测 IE 并使用此 API 的代码现在将失败。我还没有看到这种情况发生,但我注意到从 IE11 欺骗 IE10 代理字符串会导致脚本错误。
  • @LukePuplettdustin diaz 实现是基于特征检测而不是浏览器检测。你指的是这个吗?
【解决方案2】:

任何人仍在进行此讨论但没有找到他们正在寻找的答案结帐:
http://dustindiaz.com/rock-solid-addevent

对于我们这些限制使用框架的人来说,这是我发现的最优雅的解决方案之一。

function addEvent(obj, type, fn) {

    if (obj.addEventListener) {
        obj.addEventListener(type, fn, false);
        EventCache.add(obj, type, fn);
    } else if (obj.attachEvent) {
        obj["e" + type + fn] = fn;
        obj[type + fn] = function() {
            obj["e" + type + fn](window.event);
        }
        obj.attachEvent("on" + type, obj[type + fn]);
        EventCache.add(obj, type, fn);
    } else {
        obj["on" + type] = obj["e" + type + fn];
    }

}

var EventCache = function() {

    var listEvents = [];
    return {
        listEvents: listEvents,
        add: function(node, sEventName, fHandler) {
            listEvents.push(arguments);
        },
        flush: function() {
            var i, item;

            for (i = listEvents.length - 1; i >= 0; i = i - 1) {
                item = listEvents[i];
                if (item[0].removeEventListener) {
                    item[0].removeEventListener(item[1], item[2], item[3]);
                };

                if (item[1].substring(0, 2) != "on") {
                    item[1] = "on" + item[1];
                };

                if (item[0].detachEvent) {
                    item[0].detachEvent(item[1], item[2]);
                };

                item[0][item[1]] = null;
            };
        }
    };
}();

addEvent(window, 'unload', EventCache.flush);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    • 1970-01-01
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多