It took me a bit to figure out the right way of handling events in JavaScript

June 21st, 2012

When I first started to learn JavaScript in school, one of the things that I found confusing is that there’s a hundred ways to do everything. And to make it even more confusing, there’s a hundred people that will tell you each way is the best or right way to do it. Handling events is one of those things in the language that you can write multiple different ways and I know even now, I see people writing tutorials using the techniques from 15 years ago. I think looking at click events might be a good way to figure out which one is the best way to write your code.

One thing that drives me crazy is when I see inline JavaScript event handlers. Here’s an example:

<div class="box"></div>
<a href="#" onclick="changeBG(); return false;">Change BG color</a>

Let’s say we had a function that changed the background color of our div with the box of class. Now when we click the Change BG color link, it will trigger the onclick handler and fire the changeBG function. Simple, easy to write and technically nothing wrong with it, except for one thing, it’s a best practice to separate your HTML, CSS and JavaScript into different files. So, unless you’re desperate, don’t do this. And please, please don’t do this:

<body onload=”init();”>

You won’t believe how many tutorials and examples by people who are really smart have this.

Then next way to add a click event is to use something like elem.onclick. Again, there’s nothing really wrong with doing it this way, but you can run into a problem. Take a look at this:

With that code, when you click on the box, it’s background color should change to blue and it should get a 5 pixel thick border around it. But we only get the border. I know if I really wanted this to work, I should only have one onclick event, but I want to use this example to show you the problem. Let’s say in your code, after the user performs some action, you want to add another event handler onto an element but still have the original event handler on it. If you try to add that with another onclick event, it will cancel out the original event you had. If you’re building a JS heavy site or a web app, this could definitely become a problem.

The best method to use is addEventListener, which works in every browser except Internet Explorer 8 and lower, but those support an IE only version called attachEvent and you can write a few lines of code and so it will work in all browsers. Why is addEventListener the best way to go? Take a look at this example:

The first thing you’ll notice is, unlike with onclick, we are able to add more than one event listener to one element. We’re also able to use removeEventListener so you can remove the listener after the click so that you don’t have to worry about a user clicking on something an extra time and causing an error in a program. addEventListener gives you far more control than the other two options.

I’m actually really surprised at how often I see experienced programmers using the inline version, especially onload in the body tag. And I’ll be honest, no matter how experienced you are, if I see you using that or something similar in your code, I wonder if the rest of your code is up to date. Use addEventListener, it gives you the most control and it works in every modern browser.

One Response to It took me a bit to figure out the right way of handling events in JavaScript

  1. Shawn says:

    The reason is because addEventListener is inconsistent between browsers, and often doesn’t work as expected, especially on newer HTML5 API’s. Often the events just aren’t fired when they should be.

    Inline’s / callback’s are generally rock solid, that’s why you see so much use from them in the field.

    That’s the thing with HTML, you have to go with what you know works, otherwise you open the door to endless hours of debugging edge cases.

Leave a Reply

Your email address will not be published. Required fields are marked *