Category Archives: JavaScript

How to cancel events in JavaScript

If you’re writing client-heavy interactive JavaScript applications you’ll have to deal with events a lot. Most people who have come this far will have learned that you can return false at the end of an event to cancel it. But this is not the best way to go about it.

Sample code:

function my_onclick (event) {
	do_some_processing();
	return false;
}

The largest downside is: if an Error occurs in your event handler, the function will not return but throw an Error instead. This means your event is not cancelled. This is particularly embarrassing if the default action is something that you don’t want to have happen, such a submit on a form with an invalid action. You could surround your code with a try-catch statement but since there is a better solution, let’s not get into that.

Another disadvantage is that return false is not equivalent to event.preventDefault(). It also triggers event.stopPropagation(). Most of the time you only need event.preventDefault(). It’s worth noting that some event related features can not be built if you don’t distinguish between these two (see below).

So how do you do it?

Well, you call the right function for the right job. You can use event.preventDefault() to cancel the default behaviour. Prevent a page change when you click on a link. Prevent a submit on a form (AJAX anyone?). Prevent a focus on an input. Prevent a check on a checkbox.

You can use event.stopPropagation() to trap events; to prevent them from going up the DOM-tree. For instance: if you have a tooltip that you want to close when you click anywhere on the page, except not when you click on the tooltip itself. Add an onclick handler that does an event.stopPropagation() on the element that contains the tooltip and you’re done. This doesn’t break any functionality. Links still work in the tooltip, and other things with click events such as input elements. I bet you didn’t think it was that simple huh? Well, it is. This is why events are awesome.

Where did this come from? Why aren’t people just calling the right function? Honestly this isn’t so complex.

I think this might stem from a browser incompatibility. Internet Explorer has event.cancelBubble where other browers use event.stopPropagation. return false works in all browsers.

foreach in JavaScript

I assume you know about JavaScript’s for (key in object) loop and the function hasOwnProperty.

hasOwnProperty filters inherited properties. You might write your for-in-loop like this:

var my_obj = {
	foo: "bar"
};

function my_map(my_obj) {
	var key;
	for (key in my_obj) {
		if (my_obj.hasOwnProperty(key)) {
			console.log(key, my_obj[key]);
		}
	}
}

But there is a case that will fail. Can you see it? What do you think happens if I give it this object?

var my_obj = {
	hasOwnProperty: function () {
		return false;
	},
	"nothing to see here": "move along"
};

So what’s the solution?

function my_map(my_obj) {
	var key;
	for (key in my_obj) {
		if (Object.prototype.hasOwnProperty.call(my_obj, key)) {
			console.log(key, my_obj[key]);
		}
	}
}

Now isn’t that cool?

Readability vs Performance

A question that pops up often on StackOverflow is: which method is better x or y?

For example, which is better?

lazy-or

if ($a === "foo" || $a === "bar" || $a === "baz") {
    do_something();
} else {
    do_something_else();
}

in_array

if (in_array($a, array("foo", "bar", "baz")) {
    do_something();
} else {
    do_something_else();
}

There are several ways to approach this. A clever programmer might say: Faster is better right? Let’s benchmark! So he writes a script to accurately time the difference.
That’s not so easy as it may seem. The performance characteristics vary case-by-case.
What if you have not 3 but 10 values? What if you have 100? What if the first case is the most likely case and the other 2 only rarely get hit?

Let’s take a step back. In this example, does it really matter which method is faster? I would argue: no. Imagine your program has a bottleneck in it, you’re tasked with finding it and resolving it. If you saw either of these code samples, would you bother trying to see if the bottleneck is here? No, of course not. If you saw this code and you had to add a value would you take the time to convert one form to the other? Probably not (I wouldn’t).

That is why in almost all cases performance doesn’t matter. If your input is really really small (< 10) don't bother with optimization.
What you should bother with is readability. Which of these methods is more readable? I would say, in this case, it doesn’t really matter. If the list gets a bit bigger to 4 or 5 values then maybe the in_array one is preferred because it will fit on one line. If your list of allowed values is a dynamic list, because of a clever algorithm, then sure, go for the in_array variant. If you see the lazy-or variant and you need to add a 4th case, I wouldn’t object if you added another || case.

Most of the arguments I use are arguments that come from experience. Seeing a lot of code, seeing code that works and code that doesn’t. The most common way to get a bug is to write code that is easy to misunderstand or misuse. And even as a novice programmer you know this. What you don’t know is whether the code you’re currently writing is well readable or not. You haven’t yet learnt the warning signs of smelly code. A general rule of thumb: simpler is better. Simpler code is easier to write, easier to read, easier to debug, faster to write and it probably performs really well.