Classy Query

NOTE: This was an April Fools joke for April 1st, 2008.

Over the past two years, seeing hundreds of thousands of people use jQuery, a major point has become apparent: jQuery simply isn’t able to scale to handle the development needs of most power users. It lacks the clarity and power functionality that most developers need in order build applications in a collaborative environment.

For this reason I’ve put a lot of work into a new library (which sits on top of jQuery), called:

Classy Query

If one thing has become apparent to me it’s that users enjoy working with the typical Class-style of object creation and inheritance. Because of this I’ve constructed the entirety of Classy Query in an classical manner (you can inherit and override any piece of functionality that you desire).

Before we go too far, let’s take a look at the type of clearly-defined code that you can now write with Classy Query:

You can even sub-class functionality, creating your own pieces of encapsulation. All of the class and inheritance functionality is taken care of by the Simple JavaScript Inheritance code released last week.

jQuery.DOM.boldWrapInner = jQuery.DOM.wrapInner.extend({

attach: function(elem){

this._super(elem, "<b></b>");

}

});

jQuery.querySelectorAll("div").forEach(function(elem){

jQuery.DOM.boldWrapInner(elem);

});

Additionally you can treat pieces of functionality as if they were attachable behaviors, like so:

It’s possible to inherit from any existing piece of Classy Query functionality, supporting a true ‘programming in the large’ mindset. You can inherit from, or completely override, existing methods with ease (especially since they’re all classes).

jQuery.Effects.collapse = jQuery.Effects.buildAnimation.extend({

attach: function(elem){

this._super(elem, {height: "hide", width: "hide"});

}

});

Behaviors

Behaviors tend to encapsulate a portion of functionality which is applied against an element (such as making a table sortable or making an item draggable). Classy Query supports a technique to make this particular implementation trivial.

jQuery.querySelectorAll("div")

.attach(new jQuery.DOM.addClassName("current"));

No more ‘this’

The ‘this’ keyword is confusing and frequently misused. To counter this all access to elements (within functions) is done by the first argument, rather than through ‘this’.

jQuery.querySelectorAll("div").forEach(function(elem){

jQuery.DOM.addClassName(elem, "current");

});

Re-Structuring

The hierarchy of jQuery has been completely re-organized. Rather than having a single, flat, interface through which to access all methods functionality has been broken down into individual groupings of methods. These groupings tend to, also, coordinate with the jQuery Documentation for convenience.

Additionally, nearly all the method names have been re-named in order to provide a greater level of clarity to developers. Frequently it was found that the concise method names of jQuery provided too much confusion to developers just getting started with the library. The end result is a library that is easier to read and understand for developers.

The full list of categories and changed methods can be found in the following table:

jQuery

Classy Query

jQuery

jQuery.querySelectorAll

each

forEach

prepend

jQuery.DOM.prepend

append

jQuery.DOM.append

before

jQuery.DOM.insertBefore

after

jQuery.DOM.insertAfter

wrap

jQuery.DOM.wrap

wrapInner

jQuery.DOM.wrapInner

wrapAll

jQuery.DOM.wrapAll

clone

jQuery.DOM.clone

empty

jQuery.DOM.empty

remove

jQuery.DOM.remove

replaceWith

jQuery.DOM.replaceWith

removeAttr

jQuery.DOM.removeAttribute

addClass

jQuery.DOM.addClassName

hasClass

jQuery.DOM.hasClassName

removeClass

jQuery.DOM.removeClassName

offset

jQuery.DOM.getOffset

text

jQuery.DOM.getText

text

jQuery.DOM.setText

html

jQuery.DOM.getHTML

html

jQuery.DOM.setHTML

attr

jQuery.DOM.getAttribute

attr

jQuery.DOM.setAttribute

val

jQuery.DOM.getValue

val

jQuery.DOM.setValue

height

jQuery.DOM.getHeight

height

jQuery.DOM.setHeight

width

jQuery.DOM.getWidth

width

jQuery.DOM.setWidth

css

jQuery.DOM.getCSS

css

jQuery.DOM.setCSS

children

jQuery.Traverse.getChildElements

find

jQuery.Traverse.getDescendantElements

next

jQuery.Traverse.getNextSiblingElements

nextAll

jQuery.Traverse.getAllNextSiblingElements

parent

jQuery.Traverse.getParentElements

parents

jQuery.Traverse.getAncestorElements

prev

jQuery.Traverse.getPreviousSiblingElements

prevAll

jQuery.Traverse.getAllPreviousSiblingElements

siblings

jQuery.Traverse.getSiblingElements

filter

jQuery.Traverse.filterSelector

bind

jQuery.Events.addEventListener

unbind

jQuery.Events.removeEventListener

trigger

jQuery.Events.triggerEvent

hover

jQuery.Events.hover

toggle

jQuery.Events.toggle

show

jQuery.Effects.show

hide

jQuery.Effects.hide

toggle

jQuery.Effects.toggle

animate

jQuery.Effects.buildAnimation

queue

jQuery.Effects.queue

dequeue

jQuery.Effects.dequeue

$.ajax

jQuery.Ajax.request

load

jQuery.Ajax.loadAndInsert

ajaxSetup

jQuery.Ajax.setup

serialize

jQuery.Ajax.getSerializedString

serializeArray

jQuery.Ajax.getSerializedArray

querySelector and querySelectorAll

Finally, rather than having a generic, catch-all, method as jQuery selector functionality is deferred to the new querySelector and querySelectorAll methods. These methods only support pure CSS 1-3 selectors (nothing extra) in an attempt to avoid any unpleasant situations when a browser’s native querySelectorAll is implemented.

I hope this particular library will be of use to the general jQuery-using population. I hope we can start to have an open dialog, moving forward, getting everyone to adopt a more standard approach to JavaScript development. There’s no reason why we shouldn’t be using this tried-and-true approach to application development. It’s worked in an untold number of existing applications, it’s bound to work here as well. Enjoy.

Wouldn’t class behavior actually be useful for some people? It’s nice to know how easy it is to change the name of everything. You could make jQuery look like YUI (eg YAHOO.util.Dom.getStyle) really easily.

Now all you need is a script to convert old jQuery code to the new classier kind, so we don’t accidentally leave all that confusing concise old code lying around where a new developer might find it, and, not knowing any better, try to imitate it.

Creating animations is still quite a mess. You should introduce a factory, making the code more verbose, more readable and easier understandable, something like this:

// pass window and document to the animation factory factory method,
// enabling us to create animations for other windows/documents as well
var animationFactory = jQuery.Effects.createAnimationFactory(window, document);

Awesome, this really gives plain old jQuery the power boost it needed. Nice work! I measure the usefulness of code I write in how long it takes to type the idioms, so you’re definitely on the right track with this :p

Sounds awesome – I think this addresses the only two reservations I really had about jQuery. A growing library really needs clear and well organized namespaces, and classical inheritance is so well suited to so many of my needs; I can’t wait to play with it!

Firstly I get frustrated with the term ‘class’ being associated with Javascript. It can cause confusion with Javascript being a prototypal OO language.To the user Classy Query is just using namespaced functions to perform its operations as opposed to functions on a prototype. In Java, one would generally call the equivalent approach a static method rather than a class method. Maybe call it Staticy Query :)

Also, usually I’d really advocate strong namespacing to clearly organise code libraries, but in jQuery’s case I think it might be a bit overkill. For a library which is likely to be used as commonly as jQuery within a particular codebase, the extra namespacing could make code too verbose (this a problem with YUI) I think jQuery.append() etc will suffice. Further package namespacing should be reserved for extensions, eg: jQuery.ui.draggable();

Besides these points I really like the approach your taking here. Although, I think jQuery’s great, I don’t like the way it has the potential to masquerade itself as a scripting language on top of Javascript. This will make pedantic JS developers such as myself much happier :)

One of the most serious jokes I’ve seen in a long time. I had to actually click myself here from the rss reader and read the comments before I could be 100% sure that it was in fact a joke and not insanity. Awesome!