Related: Why you don't need jQuery as an abstraction
$
itself is a god object. Everything goes on it. The standard plugin / extension architecture that is recommended is to just bolt more methods on $
itself!
Surely this is bad. An example would be how we have both $.load
which is overloaded to do completely different things. If they were on two separate sensibly named objects $Container.load
and $EventTarget.load
. Personally I would deprecate the latter in favour of .on('load'
The animation should be it's own little modular thing, not bolted onto $
. Ajax should be it's own little modular thing, not bolted onto $
This is overloaded to three functions. It would be more sensible to have select
, construct
and domready
as there seperate entities.
When creating elements using the jQuery API it calls jQuery.fn.attr.call( selector, context, true );
which basically means the props run through the minefield that is .attr
. That's just great...
Also props like width
and height
don't set the width and height properties, they run the width and height methods.
We have some subset of $.ajax
short cuts which are uneven. These should be removed.
What does it even do? It doesn't just set / get attributes. It does a whole bunch of weird logic for backwards compat.
Useless, slow utility selectors. Having these things promotes bad and slow code. You wouldn't want to use them for performance penalities. They also make the CSS selector a joke by throwing propitiatory selectors in the mix.
At least split the selector engine into two, one that adheres to (a subset of) standards and one which have their own extensions.
css isn't bad as such. But it's overused, a lot. We do need a cross browser style manipulation utility but we don't need documentation recommending you use it everywhere.
The community seems to forget the massive penalty that is causing re flows. editing in-line css is slow and should be avoided
Another overloaded method that shouldn't be overloaded, that's just plain confusing
These shouldn't exist.
Doesn't match the .forEach
, .map
, etc signature. Massively confusing
Hey, lets flatten the returned array! Surely that's an useful "feature"!
domManip executes all scripts irregardless of their status. It does not bother to check whether they are inserted into a document nor does it bother to check whether their "already started" flag is set.
The first is a flag indicating whether or not the script block has been "already started". Initially, script elements must have this flag unset (script blocks, when created, are not "already started"). The cloning steps for script elements must set the "already started" flag on the copy if it is set on the element being cloned.
Function.prototype.bind
exists. Pick a better name
jQuery never gives any error messages and tries as hard as possibly not to fail or bubble up internal exceptions. It just likes to swallow all errors.
It only reads from data-
properties once on load and never reads/writes to them again. This is frustrating.
Either it shouldn't have anything to do with data-
properties or it should be a cross browser .dataset
emulation, not some kind of halfway in between thing.
This does not help debugging at all.
extend only deep copies "plain objects". Which is rather useless if you use prototypical OO because properties with enumerable non-own properties are not plain.
This basically means the deep extend is a joke and should be avoided. There is no warning about this "feature".
jQuery has no modularity. Want just ajax? Load the entire library. Want just events? load the entire library. This is simply a side effect of bad design and god objects. jQuery assumes every method exists, and everything references everything else.
The plugin model is simply bolt stuff onto $.fn
which is basically the jQuery "class". There is absolutely no attempt at promoting sub classing here. There is also no mechanism for conflict resolvement.
Basically if you want to extend jQuery your encouraged to just add layer on top of layer on the already huge god object.
Another name that's overloaded for $.get
and $.fn.get
.index()
is overloaded with 3 behaviors, but their differences can be confusing
// v---get index v---from collection (siblings is implied)
$('selector').index();
// v---from collection v---get index
$('selector').index(element);
// v---get index v---from collection
$('selector').index('selector');
The first one is understandable if you remember that it only operates on the first element
The second one makes the most sense since jQuery methods usually operate on an entire collection.
I have some concerns with jQuery's event handling/data storage system. It is praised because it doesn't add functions to on[event] properties that can close around other elements, creating memory leaks in IE. Instead it places a lightweight expando property, which maps to an entry in jQuery.cache, which holds handlers and other data.
I believe it then attaches a handler with in turn invokes the handler that you assigned. Or something like that.
Whatever the system is doesn't really matter. The point is that the connection between the element(s) and the jQuery.cache is that expando.
Why is that a big deal? Well philosophically jQuery is not a framework; it is a library. It would seem that as a library you should be able to use or not use the jQuery functions without concern for negative effects. Yet if you go outside jQuery when removing elements from the DOM, you've orphaned any handlers and other data associated with those elements via the expando, creating a nice and fully cross-browser memory leak.
Useless method. Why would multiple libraries use the same $
, name a single library that also uses $
and should be loaded on the same page as jQuery. If a developer uses prototype and jQuery on the same page or god forbid multiple versions of jQuery on the same page then they are doing it wrong. jQuery should not give them a tool to allow them to make that mistake.
The third one is entirely confusing. The method gives no indication of which selector is the collection and which selector represents the element whose index you want from the collection.
Will not work with an array argument when it's clearly obvouis what it should do.
Will not extend the current jQuery object. It will only extend jQuery itself.
what are your suggestions? prototype?