In my experience, non-clickable links and non-submitable
forms are much bigger problems.
Part of that is authors that can't (or won't) write documents that
work without scripting.
A bigger problem is that scripts create phony Ajaxified links, but
they don't look before they leap (i.e. they assume that all required
features are present and usable.)
For years, most of the freebie "cross-browser" scripts relied on
browser sniffing in lieu of feature testing. These scripts used to be
downloaded piecemeal from sites like Dynamic Drive. Later the trend
became large, monolithic libraries that attempted to solve "common"
browser scripting problems (as their authors see them.) In any event,
users of these scripts (e.g. Website developers, application
developers) rely on blind faith in the authors.
Interesting that ten years after browser sniffing had been determined
unfeasible, jQuery is "leading" the pack to switch to feature
testing. Unfortunately, having spent those years learning nothing,
the authors of jQuery were not up to the task. The "feature testing"
implemented in the latest rewrite of jQuery purports only to support
Opera 9+, FF3+, Safari 3+ and IE. Fails miserably at that.
I glanced at their much ballyhooed replacement code last week as it
was the subject of a complaint about memory leaks in IE.
http://groups.google.com/group/jquery-dev/browse_thread/thread/d127129441e26e52#
(function(){
jQuery.support = {};
var root = document.documentElement,
script = document.createElement("script"),
div = document.createElement("div"),
id = "script" + (new Date).getTime();
Interesting start. No test to see if root is defined. No check for
createElement. Stored references to host objects.
div.style.display = "none";
No test for the style property.
div.innerHTML = ' <link/><table></table><a href="/a"
style="color:red;float:left;opacity:.5;">a</a><select><option>text</
option></select><object><param/></object>';
XHTML markup and the innerHTML property don't mix. No test for this
proprietary property and all but one of the following tests could have
done without it (feature tests should be as simple and direct as
possible.)
var all = div.getElementsByTagName("*"),
a = div.getElementsByTagName("a")[0];
No test for gEBTN.
// Can't get basic test support
if ( !all || !all.length || !a ) {
return;
}
Short-circuit *all* of the tests because gEBTN didn't work with "*" or
the XHTML assignment failed to create elements? That is mind-
boggling.
jQuery.support = {
// IE strips leading whitespace when .innerHTML is used
leadingWhitespace: div.firstChild.nodeType == 3,
Certainly didn't need to skip that due to gEBTN failings.
// Make sure that tbody elements aren't automatically inserted
// IE will insert them into empty tables
tbody: !div.getElementsByTagName("tbody").length,
// Make sure that you can get all elements in an <object> element
// IE 7 always returns no results
objectAll: !!div.getElementsByTagName("object")[0]
.getElementsByTagName("*").length,
// Make sure that link elements get serialized correctly by
innerHTML
// This requires a wrapper element in IE
htmlSerialize: !!div.getElementsByTagName("link").length,
Make sure an XHTML LINK element is error corrected to HTML when
descended from a DIV and created with innerHTML? This is used for a
dodgy object inference in the function that turns HTML into nodes.
// Get the style information from getAttribute
// (IE uses .cssText insted)
style: /red/.test( a.getAttribute("style") ),
They just mark land mines as they step on them. Their map(s) would
have been out of date in the year 2000.
// Make sure that URLs aren't manipulated
// (IE normalizes it by default)
hrefNormalized: a.getAttribute("href") === "/a",
Land mine #2. That should have been enough to spot the well-known
pattern.
// Make sure that element opacity exists
// (IE uses filter instead)
opacity: a.style.opacity === "0.5",
Browser sniffing by object inference. Implies DirectX filters exist
for UA's without opacity style support. No wonder they keep lopping
off the old browsers from the supported list. Pretty pitiful to let
them crash and burn on something as simple as opacity.
// Verify style float existence
// (IE uses styleFloat instead of cssFloat)
cssFloat: !!a.style.cssFloat,
Also a bad inference.
// Will be defined later
scriptEval: false,
noCloneEvent: true,
boxModel: null
};
script.type = "text/javascript";
try {
script.appendChild( document.createTextNode( "window." + id +
"=1;" )
);
Well, this is no good at all. If there's one thing we've been over a
million times, it is dynamic script injection. I think the discussion
dates back to 2003. The point is to test whether the snippet
executes. Unfortunately, this rendition tests whether a UA can append
a child to a script node. Odd, that it looks a bit like the test in
my library. It's like they copied it but didn't understand what they
were copying.
} catch(e){}
root.insertBefore( script, root.firstChild );
The root variable may be undefined at this point.
// Make sure that the execution of code works by injecting a script
// tag with appendChild/createTextNode
// (IE doesn't support this, fails, and uses .text instead)
So they didn't understand what they were supposed to be testing.
Obviously the failure of the first test does not imply the existence
of a text property. Certainly it does not imply that it will do
anything if set.
There's a third branch too (innerText IIRC.)
if ( window[ id ] ) {
jQuery.support.scriptEval = true;
delete window[ id ];
}
The usual bad assumptions regarding the window object.
root.removeChild( script );
if ( div.attachEvent && div.fireEvent ) {
Ineffectual feature detection (by type conversion) and browser
sniffing by object inference. Wants to test whether cloned nodes
preserve attached listeners. Infers that only UA's with attachEvent
and fireEvent are suspect (likely IE in the minds of the authors.)
div.attachEvent("onclick", function(){
Circular reference involving a host object.
http://www.jibbering.com/faq/faq_notes/closures.html#clMem
// Cloning a node shouldn't copy over any
// bound event handlers (IE does this)
jQuery.support.noCloneEvent = false;
div.detachEvent("onclick", arguments.callee);
This is the only shot to plug that leak.
});
div.cloneNode(true).fireEvent("onclick");
}
// Figure out if the W3C box model works as expected
// document.body must exist before we can do this
jQuery(function(){
Odd that feature testing code would need to create a new jQuery.
var div = document.createElement("div");
div.style.width = div.style.paddingLeft = "1px";
document.body.appendChild( div );
jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth ===2;
Which style did they forget? And AIUI, this flag is deprecated, which
means that after all of these years of trying, they are giving up on
supporting IE quirks mode. As with "old" browsers like Opera 8 and
FF2, they will simply cut the tether, meaning the next compulsory
upgrade will break every site, app and plug-in ever built and tested
in quirks mode (and nobody will help you fix them.)
document.body.removeChild( div ).style.display = 'none';
That's the first I've seen that one. If you remove a node, do you
really care about its display style?
});
Assuming the fireEvent test completes, it looks like "Drip" is
mistaken. Hard to say for sure though (that is what Task Manager is
for.) Also hard to imagine why this line is missing:
root = div = script = null;
At the very least, that will make "Drip" shut up. The fact that such
logic is missing is the sort of glaring omission that is typical of
jQuery. Not surprising that it wasn't suggested either.
})();
Why these support.* properties are exposed for others to infer God
knows what from is anyone's guess. Seems a recipe for disaster,
especially since the meaning of these flags is undocumented (and
unknown even to the author.) Lets see, if flags A, B and C are set,
but not D, then it is safe to call method X (at least until the next
upgrade.)
These flags aren't of much interest to calling apps anyway. Where's
the indication that Ajax is available or centering an element is
possible? There is none, so the apps blunder into broken "lightboxes"
and other ill-advised aspirations. Never mind that end-users *hate*
(or are at best ambivalent about) such things.
The developers write what *they* want. They like animations and new
"skills" on their résumé. However, they won't like it when these
ridiculous HTML/JS concoctions go the way of the Dodo. It won't be
the fault of the language or the browsers either.
As for jQuery specifically, there's no fixing it at this point.
Lopping additional browsers off the supported list is clearly not an
option. Even if they knew how to fix it, they can't release a new
revision every month and there is too much broken to fix all at once.
They should just admit defeat. Seems most of the remaining "supported
browsers" have selector queries and animations built-in anyway.