Correct usage of addEventListener() / attachEvent()?

89,960

Solution 1

The usage of both is similar, though both take on a slightly different syntax for the event parameter:

addEventListener (mdn reference):

Supported by all major browsers (FF, Chrome, Edge)

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

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

Events list for addEventListener.

attachEvent (msdn reference):

Supported by IE 5-8*

obj.attachEvent('onclick', callback);

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

Events list for attachEvent.

Arguments

For both of the methods the arguments are as follows:

  1. Is the event type.
  2. Is the function to call once the event has been triggered.
  3. (addEventListener only) If true, indicates that the user wishes to initiate capture.

Explanation

Both methods are used to achieve the same goal of attaching an event to an element.
The difference being is that attachEvent can only be used on older trident rendering engines ( IE5+ IE5-8*) and addEventListener is a W3 standard that is implemented in the majority of other browsers (FF, Webkit, Opera, IE9+).

For solid cross browser event support including normalizations that you won't get with the Diaz solution use a framework.

*IE9-10 support both methods, for backwards compatibility.

Thanks to Luke Puplett for pointing out that attachEvent has been removed from IE11.

Minimal cross browser implementation

As Smitty recommended you can use this Dustin Diaz addEvent implementation for a solid cross browser implementation without the use of a framework:

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

Solution 2

Anyone still hitting this discussion and not finding the answer they were looking for checkout:
http://dustindiaz.com/rock-solid-addevent

This is one of the most elegant solutions I found for those of us with restrictions on using the frameworks.

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);
Share:
89,960

Related videos on Youtube

ginny
Author by

ginny

Updated on November 18, 2021

Comments

  • ginny
    ginny over 2 years

    I'm wondering how to use addEventListener respectively attachEvent correctly?

    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);
    }
    
     // ...
    

    or

    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);
    }
    
     // ...
    

    ?

    Is this cross-browser secure or should I better go with something like this:

    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: Say myfunc2 is for IE 7 only. How to modify the correct/preferred method accordingly?

    • Pointy
      Pointy about 14 years
      You may not like me for saying this, but why wouldn't you just use a framework to deal with such issues?
    • ginny
      ginny about 14 years
      I would but I can't in this case. So, could you help me with this, please?
    • hitautodestruct
      hitautodestruct over 11 years
      @ginny Have a look at my answer. Let me know if you need any further explanation than that.
    • MrWhite
      MrWhite over 11 years
      At the very least, you shouldn't be testing for the event model everytime you want to register an event. This can be easily separated into a common function, to which you pass the element, event type and handler.
  • hitautodestruct
    hitautodestruct almost 12 years
    @CamiloMartin It's always worth while to put in a good answer if you get a comment like this afterwards, Thanks :)
  • MrWhite
    MrWhite over 11 years
    addEventListener is also supported by IE9+.
  • Luke Puplett
    Luke Puplett over 10 years
    attachEvent has been removed in IE11, so code that detects IE and uses this API will now fail. I've not yet seen this happen but I have noticed that spoofing IE10 agent string from IE11 can cause script errors.
  • hitautodestruct
    hitautodestruct over 10 years
    @LukePuplett The dustin diaz implementation is based on feature detection not browser detection. Is that what you are referring to?