正确使用addEventListener()/ attachEvent()?

时间:2010-04-17 04:05:47

标签: javascript addeventlistener attachevent

我想知道如何正确使用addEventListener attachEvent

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。如何相应地修改正确/首选方法?

2 个答案:

答案 0 :(得分:121)

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

addEventListener(mdn reference):

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

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

Events list

attachEvent(msdn reference):

obj.attachEvent('onclick', callback);

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

Events list

参数

对于这两种方法,参数如下:
1.是事件类型。
2.触发事件后是否调用该函数 3. (仅限addEventListener如果为true,则表示用户希望启动capture

解释

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

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

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

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

最小的跨浏览器实现

正如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' )
})

答案 1 :(得分:6)

任何人仍在进行讨论而没有找到他们正在寻找结账的答案:
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);