Javascript Tagging System

Aim

I needed a way for users to browse through the projects on my site using tags, but I didn't want the tagging system to be based server side. If it was server side you'd have excessive lag and added server stress, all for merely rearranging the same content. Thus, the only real option for client side programming was Javascript. All I wanted was to write up a list of comma separated tags and have the tagging system automatically handle the rest.

Written tags (python, graphics...) => HTML tags (<a href="#"...>python</a>...) => Show/Hide

Initial Implementation

The initial implementation was done in only a few minutes with fairly standard Javascript for handling the HTML tag creation and the show and hide functionality handled by Jquery (fadeIn and fadeOut respectively). This initial implementation seemed to work well, and had all I basically wanted - the issue was when my friend asked me how the system scaled - how many entries could it handle without dying?

Turns out it wasn't as much as one might have thought or liked... At ~40 we hit Matrix bullet time (ie, freeze frame)

"Generic uhoh" - this needs to be fixed. I could understand if it choked and died at 150 or 200 entries, but 40 entries is well within the realm of possibilities - and worse than that this is all on relatively modern and powerful computers! Even though Javascript isn't known as a fast language I'd seen it in the past handle some huge data sets - thus it fell to the fault of the programmer.

You may hate to admit it, but if it doesn't work, chances are it's your fault ^_^

Optimising the Beast (or why Jquery is so damned pretty...)

The original coding was similar to the following...

for (i=0; i < $(".entry").length; i++) {
	var curr = $(".entry")[i];
	if ($(".tags", curr ).text().indexOf(tag) == -1) $(".entry:eq("+i+")").fadeOut("slow");
	else $(".entry:eq("+i+")").fadeIn("slow");
}

One of Jquery's greatest strengths is it's ability to use selectors and chain functions creatively. Using this, the code ended up as two lines -

$("div.entry:hidden > div.taglinks:contains('" + tag + "')").parent().fadeIn();
$("div.entry:visible > div.taglinks:not(:contains('" + tag + "'))").parent().fadeOut();

There are a few core ideas going on here -

Comments

Comments yet to load...