10

In order to add events we could use this simple first solution:

function AddEvent(html_element, event_name, event_function) 
{       
   if(html_element.attachEvent) //Internet Explorer
      html_element.attachEvent("on" + event_name, function() {event_function.call(html_element);}); 
   else if(html_element.addEventListener) //Firefox & company
      html_element.addEventListener(event_name, event_function, false); //don't need the 'call' trick because in FF everything already works in the right way          
} 

or this second solution (that adds inline events):

function AddEvent(html_element, event_name, event_function) 
{       
   var old_event = html_element['on' + event_name];
   if(typeof old_event !== 'function')
      html_element['on' + event_name] = function() { event_function.call(html_element); };
   else
      html_element['on' + event_name] = function() { old_event(); event_function.call(html_element); };
}

These are both cross-browsers and can be used in this way:

AddEvent(document.getElementById('some_div_id'), 'click', function() 
{             
   alert(this.tagName); //shows 'DIV'
});  

Since I have the feeling attachEvent/addEventListener are used more around in events handling implementations, I'm wondering:

Are there any disadvantages/drawbacks against using the second solution that I might better be aware of?

I can see two, but I'm interested in more (if any):

  1. the second solution screws up innerHTML of elements by adding events inline
  2. Using second solution I can easily remove all functions associated with a certain event type (html_element['on' + event_name] = null), but I can not use detachEvent/removeEventListener to remove exactly a specific function.

Any answers like: "use jQuery" or any other framework are pointless!

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Marco Demaio
  • 33,578
  • 33
  • 128
  • 159
  • You forgot about the `event` parameter – Bergi Aug 11 '14 at 13:47
  • @Bergi: where, what? – Marco Demaio Aug 27 '14 at 20:34
  • In all of these `event_function.call(…)` expressions. The handler is called without an `event`! – Bergi Aug 28 '14 at 08:11
  • Thanks, but I think it's not mandatory to pass the event to the `event_function`. I agree with you that if the event handler wants to do something with the event it would need the event parameter. – Marco Demaio Sep 01 '14 at 11:47
  • What do you mean, "it's not mandatory"? I thought you wanted to write a generic addeventlistener function. You can't know that a handler doesn't use the event object. – Bergi Sep 01 '14 at 11:51
  • @Bergi: as I said you are right! I just meant that even if you do not pass the event, the function does not break! Beside the fact it never happened to me to use the event object in the handler. The question here is more about which way of the two could be the best one, rather than implementing a full featured cross browser event listener. Anyway I did appreciate your comment, please feel free to edit my question and fix the code, if you want. – Marco Demaio Sep 06 '14 at 18:24

2 Answers2

7

With the 2nd solution, you have to manually call the previous functions, making it hard to remove specific listeners (which, to me, sounds like something you'd rather want than clearing all listeners), while on the first solution, you can only clear them all at the same time, unless you want to emulate the first functionality.

Personally, I always use the first solution, because it has the advantage of not having to worry about clearing possible other event listeners.

The mozilla wiki also lists the advantages that the first solution works on any DOM element, not just HTML elements, and that it allows finer grained control over the phase when the listener gets activated (capturing vs. bubbling) with the third argument.

yorick
  • 1,474
  • 10
  • 8
  • I think you have the first thing and second thing backwards in your first 2 paragraphs. – Roatin Marth Sep 21 '10 at 19:11
  • +1 i read link you suggested, but the three points explained by Mozilla site are not that true: "1. It allows adding more than a single handler for an event" true but with both functions I wrote in answer you can add more than a single event handler. "2. It gives you finer-grained control of the phase when the listener gets activated (capturing vs. bubbling)" true, but it's easy to add stopEvent function to prevent deafault and stop bubbling, moreover attachEvent does not have such beahvior so would anyayw have to create a cross-browser function. – Marco Demaio Sep 22 '10 at 12:58
  • (continued) "3. It works on any DOM element, not just HTML elements.", interesting, but I don't see a real life example where I might need to add an event to a dom node which is not also an HTML element. – Marco Demaio Sep 22 '10 at 12:59
  • @Marco Demaio: 1. true. but your functions are non-native, and any other person who'd want to register an event, would clear out the entire onload. 2. true 3. SVG tags? – yorick Sep 22 '10 at 13:22
3

i would use both codes like this

function addEvent(html_element, event_name, event_function) {
    if (html_element.addEventListener) { // Modern
        html_element.addEventListener(event_name, event_function, false);
    } else if (html_element.attachEvent) { // Internet Explorer
        html_element.attachEvent("on" + event_name, event_function);
    } else { // others
        html_element["on" + event_name] = event_function;
    }
};
Fareed Alnamrouti
  • 30,771
  • 4
  • 85
  • 76