Switching from Prototype to jQuery
The Prototype framework has been one of my most productive investments since I adopted it over a year ago. Not only have I resorted to using the framework itself, but also learned and extrapolated from its internals. Back then I evaluated both jQuery and Prototype but the latter seemed more stable and “serious” while jQuery seemed like the hobbyist alternative trying to do too much. A week back, I revisited jQuery and chose to drop Prototype like a hot potato, making the switch to jQuery for all future projects. jQuery’s expressiveness makes it a delight to use and it really understands and addresses the common usage patterns–which in Prototype require a lot more plumbing.
CSS Selectors and Command-Chaining
jQuery has the friendliest API and syntax hands-down, designed entirely around the user. The most useful are the jQuery Selectors with support for CSS level-3 selectors, hybridized with some XPath expressions and jQuery custom filters:
$('table.orders tr:odd checkbox[name=purchase]').css('border', '1px solid black').attr('checked', 'checked');
The single line above says it all. The selector in the first set of parenthesis uses part CSS selectors to find a table element with class ‘orders’, part jQuery filters to filter only the odd rows, and part XPath expression to narrow down the selection to check boxes with the “name” attribute set to “purchase”.
Using command chaining, the selected nodes are easily updated using the css() function to add a black border, followed by attr() to add an HTML attribute checked=”checked”.
A quick glance at the jQuery Selectors reveals the large vocabulary waiting to be exploited.
DOM Traversal and Manipulation
Walking the DOM has always been a the source of confusion because it quickly gets complicated for example when you want build a menu tree which requires expanding a menu item while simultaneously collapsing other menu items at the same level as well as their children. jQuery makes it easy to traverse siblings(), children(), descendants(), parents() or the closest() nodes while also offering the not() function to specify an exclude criteria. All expressions accept the selectors applauded earlier. For example if you want to clone() the parent() of a node and append() html() inside it you would write just that:
The Event handling features are standard-issue like the other frameworks but have some other practical offerings like the hover() handler (how many times have you used the onmouseover and onmouseout pattern?), the one() handler which registers an event handle for one time use, and even a live() event handler which works for nodes added well after the event has already been registered.
These features address common developer usage patterns. There have been dozens of occasions where I have registered a one-time event handler by removing the event handler inside the callback, or re/registering an event on newly added element. jQuery pins these scenarios without going overboard with API functionality.
With Prototype a lot more plumbing had to be done by hand, and sometimes cutting and pasting snippets from prototype evangelists sharing their own solutions to the common scenarios.
jQuery’s documentation is also a pleasure to peruse if you want to find or explore new features. The visual documentation is indispensable for those just starting off with jQuery. Simon Willison’s overview of jQuery is highly a recommended read before you dive into jQuery. It is also the source for my own learning and consequently for this blog.
After spending less than 3 hours reading blog posts and perusing the documentation I was able to do a lot more in a lot less time then ever before. The huge community and neatly organized jQuery plugins make me feel like a sucker for not having jQuery for my Scrabble pet-project. jQuery is quickly gaining adoption while Prototype tries to stay light on features despite having a footprint that isn’t. I am such a sellout.
Update, Jan 17: The latest performance benchmarks came in around pretty much the same time I made this post. Prototype has embarassingly poor performance, in some cases nearly 4x worse than jQuery.