2015-01-11

Adding event listeners with JavaScript

Adding event listners in pure JavaScript is actually relatively easy and painless, take the following example:

<style>
	.highlighted { color: red; }
</style>
<p id="toggle-status">This is some text</p>
<button id="toggle-btn">Toggle the text colour</button>

<script>
	var toggleElement = document.getElementById("toggle-status");
	var toggleButton  = document.getElementById("toggle-btn");
	toggleButton.addEventListener("click", function(event) {
		toggleElement.classList.toggle("highlighted");
	});
</script>

(jsfiddle)

The above example is relatively simple, clicking the "Toggle the text colour" button should toggle the colour of the paragraph between the default (black), and red.

Let's look in more detail at the addEventListener method, it takes three arguements: the event type (e.g. 'click', 'mouseover'), the function to execute on said event firing, and a boolean value that you can use to state when the event handler should be executed (more on this later).

someElement.addEventListener("eventType", functionToExecute, false);

There are other ways to add event listeners in JavaScript, the 'traditional' way introduced in Netscape (that has a number of drawbacks) and the IE specific way, which thankfully is no longer supported as of IE 11:

var toggleButton = document.getElementById("toggle-btn");

// traditional way
toggleButton.onclick = doSomething;

// IE specific way
toggleButton.attachEvent('onclick', doSomething);

// ideal
toggleButton.addEventListener("click", doSomething, false);

The dark days

You don't really need to worry about the 'traditional' way of doing this anymore (unless you need to think about supporting pre IE5 browsers), but I'll touch on it quickly.

For those that remember the dark days before seperation of concerns, you may have seen HTML like the following:

<p>
	<font face="verdana" size="2" onClick="alert('Some annoying text')">This is some text</font>
</p>

In those early days, this used to be the only method off attaching event in JavaScript (shudder), needless to say, things progressed quickly and it was soon realised this was a poor way of attaching events, Netscape 3 introduced the 'tradional' method of attaching events in pure JavaScript, and IE of course ended up following (This was a bit before Microsoft has succeeded in killing NetScape through abuse of their monopoly position).

You can still attach events in this manner (both inline as in the example above, and in pure JavaScript), but I can see no reason why you would want to, one of the obvious drawbacks to this method is you can't assign multiple event listeners to an element, e.g.

toggleButton.onclick = doSomething;
toggleButton.onclick = null;

The above would result in clicking on said element not doing anything (the second registration overwrites the first).

Internet Explorer fun

Now onto the IE specific method, unfortunately if you need to support IE8 and below this is something you'll need to think about:

toggleButton.attachEvent('onclick', doSomething);

This is quite similar to the new addEventListener method, it's better than the traditional mehtod in the sense that you can add multiple events:

toggleButton.attachEvent('onclick', doSomething);
toggleButton.attachEvent('onclick', doSomethingMore);

You can also remove them using detachEvent, e.g.

toggleButton.detachEvent('onclick', doSomething)

There are two notable drawbacks to the IE specific method though:

  • Events always bubble
  • The this keyword always refers to the window instead of the element the event is attached to

Fortunately as stated earlier, this method is no longer supported as of IE 11, if you do need

Dealing with older versions of IE

If you want to use the addEventListener method in anything below IE 9, you'll need to polyfill this in some way, as IE 8 doesn't support the new addEventListener method.

One solution could be to implement an if statement like so:

if (toggleButton.addEventListener) {
    toggleButton.addEventListener("click", doSomething, false);
}
else {
    toggleButton.attachEvent("onclick", doSomething);
}

This definitely isn't ideal though, if the amount of JavaScript you're using is very minimal then the above is probably OK, in other cases a polyfill is probably better.

I've not played around with it, but this polyfill looks promising. There are no doubt various others available online.

What about the third parameter of the addEventListener method?

I know I earlier said I would explain this later, but I think that's maybe outside the scope of this article (I'll probably write another article covering it). If you want to find out more about it there's a great article on QuirksMode regarding it.

Linkedin Stackoverflow GitHub

About Me

I'm a web developer (mostly Front end) currently working at Studio 24 (I previously worked for an Essex based company called Intelligent Penguin).

I spend a fair amount of time messing around on the web, I'm reasonably active on Stackoverflow (link above) and I've been known to tweet occasionally.

I started this site primarily as a blog, I find it useful to write about what I learn and that's what I intend to do (hopefully my ramblings are useful to someone)!