Which is about as useful as validating HTML. Great for academic
Invalid markup is certainly not useful.
purposes, perhaps it will catch a few errors, etc.
In jQuery's case, virtually every line will have a problem (or
multiple problems.) That indicates a slap-dash effort.
But in the end it doesn't matter if code passes analytics, just if it
It matters for the people who have to maintain it. And since you are
relying on these people, it matters to you.
accomplishes the goal or not. My goal never includes "pass
validation". Validation is merely a tool to reach my goal, when
needed.
I don't know what that means. If you write invalid markup and messy
script, you invite problems.
Browser sniffing is not encouraged, and in some cases in jQuery it is
really unnecessary. There are cases where it is beneficial.
It is never beneficial.
Rather than writing lengthy logic to solve for every possible case,
you can write shorter logic to solve for a subset of cases you care
about.
Which you could do without parsing the userAgent string.
It's not ideal, but it is a strategy. The amount of browser sniffing
in jQuery is minimal.
Hardly. It is woven into many important low-level functions. Here is
a particularly stupid snippet from the get/setAttribute wrapper called
attr:
} else if ( jQuery.browser.msie && name == "style" )
return jQuery.attr( elem.style, "cssText", value );
Do you have any idea how many agents jQuery will identify as IE? Do
you have any idea how trivial it is to properly feature detect IE's
broken get/setAttribute functionality?
Forget that for the moment, why is this function passing a style
object to itself? Its first parameter is supposed to be an element.
Later in the same function, it becomes apparent (that the author is
out of his mind.)
// IE elem.getAttribute passes even for style
else if ( elem.tagName ) {
....
// elem is actually elem.style ... set the style
} else {
There couldn't be a more critical function in the entire library and
it is pure gibberish. Even the comments are senseless. There are
several additional sniffs in this same function.
if ( jQuery.browser.msie && /href|src/.test(name) && !
jQuery.isXMLDoc(elem) )
return elem.getAttribute( name, 2 );
Just what sort of XML document runs script in IE? Certainly not an
XHTML document. Realize that this absurd line of code is evaluated
every time jQuery looks at an element's attribute.
Then there is this gem:
// Certain attributes only work when accessed via the old DOM 0 way
if ( fix[name] ) {
if ( value != undefined ) elem[fix[name]] = value;
return elem[fix[name]];
This demonstrates a stunning lack of understanding of attributes (and
IE's problems with them.) Where's the sniff (or feature detect) for
IE? This IE-specific workaround runs on everything.
Still in the same function:
else if ( value == undefined && jQuery.browser.msie &&
jQuery.nodeName(elem, "form") && (name == "action" || name ==
"method") )
return elem.getAttributeNode(name).nodeValue;
No comment for this magic spell, so there is no telling what it is
trying to do. One thing is certain. This code will run on lots of
non-IE agents.
It gets worse.
if ( value != undefined ) {
if ( name == "type" && jQuery.nodeName(elem,"input") &&
elem.parentNode )
throw "type property can't be changed";
elem.setAttribute( name, value );
}
Another example of confusing attributes with properties. This is also
an IE-specific workaround with no sniff (or feature detect.)
And just when you think you have seen every conceivable miscue (all in
a single function mind you.)
if ( name == "opacity" && jQuery.browser.msie ) {
if ( value != undefined ) {
// IE has trouble with opacity if it does not have layout
// Force it by setting the zoom level
elem.zoom = 1;
What in God's name do opacity (and other styles) have to do with
attributes?
That's enough of that function. Keep in mind that the code therein is
called constantly by jQuery. Unfortunately for those who rely on
jQuery, it is error-prone, confused, inefficient and convoluted. The
design (and documentation) is of such poor quality that it is an
assault on the senses of anyone unfortunate enough to glance at it.
And speaking of opacity. In the curCSS function:
if (prop == "opacity" && jQuery.browser.msie) {
ret = jQuery.attr(elem.style, "opacity");
return ret == "" ? "1" : ret;
}
So any agent that identifies as IE and will be re-routed to the attr
function, which has nothing to do with style, but does contain more
sniffing and some IE-specific DirectX twiddling, which will have no
(positive) effect on non-IE agents.
It would seem that querying style rules would be almost as critical to
querying attributes in a library like jQuery. Yet, in this same
function you find this gem:
// A helper method for determining if an element's values are broken
function color(a){
if ( !jQuery.browser.safari )
return false;
var ret = document.defaultView.getComputedStyle(a,null);
return !ret || ret.getPropertyValue("color") == "";
}
This is the author's idea of a feature detect for getComputedStyle.
Why Safari-like browsers are excluded is a mystery. After that
inauspicious start, it blunders into the defaultView, getComputedStyle
and getPropertyValue properties with the impunity of somebody who
hasn't got a clue as to what they are doing.
It goes on and on. From the clean function:
if ( jQuery.browser.msie ) { // String was a <table>, *may* have
spurious <tbody>
if ( !s.indexOf("<table") && s.indexOf("<tbody") < 0 )
tb = div.firstChild && div.firstChild.childNodes;
div *may* have a firstChild property.
// IE can't serialize <link> and <script> tags normally
jQuery.browser.msie && [1, "div<div>", "</div>"]
You have to keep in mind while reading this stuff that
jQuery.browser.msie is meaningless on the Web. It isn't of much use
on an Intranet either, unless you use the same version and
configuration of IE forever.
// Also, we need to make sure that the correct elements are being
returned
// (IE returns comment nodes in a '*' query)
if ( jQuery.browser.msie ) {
for ( var i = 0; second
; i++ )
if ( second.nodeType != 8 )
first.push(second);
} else
Same problem different function. What if some agent that doesn't
identify as IE has the same problem? Also note how hard it is to
follow with all of the missing brackets.
More madness:
var styleFloat = jQuery.browser.msie ? "styleFloat" : "cssFloat";
Obviously you should just check (or set) them both. What happens if
IE8 switches gears on this? And what of an IE-spoofing agent that
doesn't use "styleFloat?"
// Check to see if the W3C box model is being used
boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
That could have far-reaching implications. A quick search found it in
an attempt to measure the viewport:
return this[0] == window ?
jQuery.browser.safari && self["inner" + name] || jQuery.boxModel &&
Math.max(document.documentElement["client" + name],
document.body["client" + name]) ||
document.body["client" + name] :
this[0] == document ?
Math.max( document.body["scroll" + name], document.body["offset" +
name] ) :
h == undefined ?( this.length ? jQuery.css( this[0], n ) : null ) :
this.css( n, h.constructor == String ? h : h + "px" );
I characterized this as a "million monkey" project earlier and I want
to take a moment to apologize to monkeys everywhere. I think even a
single monkey could write a better solution to this very common
problem. Certainly there are many better solutions floating around on
the Internet.
And boxmodel can also be observed in the positioning code:
// IE adds the HTML element's border, by default it is medium which is
2px
// IE 6 and IE 7 quirks mode the border width is overwritable by the
following css html { border: 0; }
// IE 7 standards mode, the border is always 2px
if ( msie ) {
var border = jQuery("html").css("borderWidth");
border = (border == "medium" || jQuery.boxModel &&
parseInt(version) >= 7) && 2 || border;
add( -border, -border );
}
There are so many misconceptions here it is hard to know where to
begin. Suffice to say that the clientLeft/Top properties hold the
needed information in IE.
In the same function:
// Mozilla and Safari > 2 does not include the border on offset
parents
// However Mozilla adds the border for table cells
if ( mozilla && /^t[d|h]$/i.test(parent.tagName) || !safari2 )
border( offsetParent );
Apparently, in the jQuery universe there is only Opera, Mozilla,
Safari and IE. IE never gets here. Opera (and Safari <= 2 if you
believe the comments) adds borders when it shouldn't. So this logic
excludes everything the author has ever heard of that isn't Opera.
Speaking of Mozilla. Does this look like a good indication of Mozilla-
based browsers?
mozilla: /mozilla/.test(userAgent) && !/(compatible|
webkit)/.test(userAgent)
Why not call that the everything-under-the-sun property?
Getting back to border issue, in the mozilla-and-newer-Safari-only
(and oddly named) border function:
add( jQuery.css(elem, "borderLeftWidth"), jQuery.css(elem,
"borderTopWidth") );
What an outrage. The author apparently never heard of clientLeft/Top.
Backing up to where boxModel was first spotted, this is deja vu:
styleFloat: jQuery.browser.msie ? "styleFloat" : "cssFloat",
Yes, this logic is repeated just three lines below the first instance.
Moving on. In the ready function:
if ( jQuery.browser.mozilla || jQuery.browser.opera )
document.removeEventListener( "DOMContentLoaded", jQuery.ready,
false );
So if it is virtually any agent, assume there is a document object (a
fair assumption) and assume that it has a removeEventListener method
(an outrageous assumption.) Why the event listener needs to be
removed at all is another interesting question. The comments
mentioned memory leaks.
Here is the flip-side of this in bindReady:
// If Mozilla is used
if ( jQuery.browser.mozilla || jQuery.browser.opera )
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", jQuery.ready,
false );
So two of the four browsers that the author knows of are known to
support DOMContentLoaded. Of course, it wouldn't hurt to add this
listener for everything. Come to think of it, he did (unknowingly)
add it for virtually everything.
You've got to love the comments. "Use the handy event callback" may
be the least informative one yet. Here's another interesting one from
makeArray:
// Need to use typeof to fight Safari childNodes crashes
if ( typeof a != "array" )
for ( var i = 0, al = a.length; i < al; i++ )
r.push( a );
else
r = a.slice( 0 );
And why would you pass an array to a "makeArray" function anyway?
This reminds me of the function test code, which was blistered in
another recent "jQuery is a joke" thread.
Enough is enough. If you use jQuery after reading this, you are
deserve everything you get.
It may not be perfect, but have you ever come across a real-world case
where it has failed for you?
Me neither.
Asked and answered? I still want to know what reak-world you are
from.
jQuery's code is not terrible. It is a substantial improvement over
most javascript code written by average developers. In my experience.
Ten years, according to a previous post, and you haven't learned a
thing. And who cares how it stacks up to "average developers?" If
you take an average JavaScript developer and give them this mess to
play with, are you really empowering them to write competent
applications?
I didn't think so either.
The packed version is 26kb. Plenty small.
Really? Define packed. Minified it is roughly 50K. GZIP doesn't
enter into it (unless you can't comprehend why it is silly to compare
file sizes after compression.) How small would a 20K library be after
compression? Regardless, you shouldn't manually compress JavaScript
files.
But why should I look up past examples? You said you recently looked
over the code and found that it was poorly written and full of
mistakes.
Sure did.
Surely you could provide some examples from your recent investigation?
Sure could.
I'm not sure "lots of people can make that claim". I consider myself
to be very knowledgeable about Javascript development, and I disagree
with your conclusions. Surely not everyone who disagrees with you is
categorically an amateur?
What you consider yourself to be is hardly relevant. If you use and
recommend jQuery, then you are worse than an amateur. You are doing a
disservice to anyone who is unfortunate enough to use your creations
or listen to your advice.
What don't I get? You are not providing any actual arguments. You
You don't get JavaScript, browser scripting, etc.
might as well just say "You're stupid!" and stick your tongue out.
If you use or advocate jQuery after today, you are stupid.
Further, have you considered that perhaps it is you who just doesn't
get it?
I've looked at that. I don't think so.
Perhaps. The point is, just because you notice a few flaws in
something does not mean it is worthless. It merely means it has flaws.
A few flaws?!
Which means it was probably developed by humans. If your goal is
perfection, you'll never find it.
Finding a library was never my goal. Regardless, there is a big
difference between competent and perfect.
#1:
(Previous time to develop functionality) - (current time to develop
similar functionality) = Time Savings
Time Savings * Pay Rate = Money Saved
Oversimplification.
#2:
(Number of JS bugs before) - (Number of JS bugs now) = Bug Savings
(Bug Savings) * (Avg Time to Fix JS Bugs) * Pay Rate = Money Saved
You've got lots of bugs and future maintenance issues. Perhaps you
didn't know about a lot of them before today. And if you can't write
relatively bug-free code without jQuery (God knows you can't with it),
then perhaps you should consider another line of work.
Consider the effects of introducing jquery to a large development
team:
[snip considerations]
Now, how are you arguing that using jquery is not a huge benefit?
I didn't read the considerations. I am tired of hearing about
jQuery. It sucks. Case closed.
You would recommend that we stop using it and start coding from
scratch?
Why do library-advocates invariably see just those two choices? Do
whatever you want.
Then how would you know anything about an increase in maintenance
caused by using jQuery?
You don't have to be psychic to see what lies ahead for your team.
Can you quote the experience of anyone else who has used it and found
it to be a maintenance problem?
I really don't talk to jQuery users. They tend to babble on and on
about nothing.
Or hell, can you quote anyone who has used it and found it to be a bad
decision for any reason?
I don't think I need to quote anyone at this point.
Do you have any real-world experience with it?
You are repeating yourself.
If not, how do you possibly feel justified in criticizing it?
See above.