Wednesday, March 4, 2009

JQuery Selector Headache

Wasted some valuable time 4 days ago, very early in the morning trying to figure out what has gone wrong with JQuery-1.3.2 and even when I tried reverting to version 1.3.1, the problem still persisted and it left me wondering if there was a bug in the 1.3 releases.

To select an element with an attribute equal to a particular value, you'd write an attribute selector like the one below:

$item = $('div[@class=scrollable]");

which would select all elements matched by DIV tag that have a class value exactly equal to scrollable. I have used that feature a million times (just joking, but I've really used it so many times) and it had always worked only to fail me today. I consulted Jonathan Chaffer and Karl Swedberg's JQuery Reference Guide to cross-check if what I was doing was wrong or something; but it validated my code and I resorted to using an alternative, which was to give that element in question an ID and select it with JQuery using that ID. Of course, this would only work for cases where you can easily assign an ID to the element in question. If there are several occurrences of such an element in the document, giving each one an ID might not work for you, though you can resort to using a consistent naming scene for the IDs.

It was only after I got the script to work after selecting the element via its ID did I remember that I saved a copy of JQuery's 1.3 release features on my hard-drive. So I perused the document and discovered that such a feature as the one I used has been changed making the new 1.3 releases backwards incompatible with such selector expressions. I just felt like posting this per-adventure someone finds [her]himself in the same fix. I have always thought that I can just point my script to use the latest release of JQuery without breaking things but I have learnt my lesson that this is not always so. I also rarely take my time to read the releases features posted about the libraries I use, but now I know that it's not a good idea to be doing that. So the change in 1.3 releases as regards the attribute selector expression I used earlier is to remove the @ to upgrade. So we now have something like this:

$item = $('div[class=scrolable]"); - v1.3 upwards

Some other notable features that could break your old scripts are:
  • Triggered events now bubble up the DOM. Unsuspecting event handlers may accidentally capture more events than they're expecting.
  • The ready() method no longer tries to make any guarantees about waiting for all stylesheets to be loaded. Instead all CSS files should be included before the scripts on the page.
  • .isFunction is simpler now, it no longer handles some strange edge cases (in favor of simplicity and performance).
  • The order of "a, b, c" style selectors may change. Browsers that support querySelectorAll (Safari, Firefox 3.1+, Opera 10+, IE 8+) will return the elements in document order, other browsers will (currently) return them in the order specified. In an upcoming 1.3.x release all comma-separated selectors will be returned in document order.
  • The trigger and triggerHandler methods no longer accept event objects within the data array. Instead they should be specified directly as an argument.
  • The undocumented 'extra' function is gone from trigger and triggerHandler functions as well.
  • The internal jQuery.event.trigger no longer returns the last item returned by a handler, instead it return true or false as per the W3C specification. You should use a jQuery.Event object to capture the specific return value.
  • You should always be sure to run your page in standards mode. There are known issues with methods not working correctly in quirks mode (including errors in the selector engine in Safari).

The following properties have been deprecated (in favor of feature detection and jQuery.support, as discussed in the Overview).

  • jQuery.browser
  • jQuery.browser.version
  • jQuery.boxModel

The following browsers are no longer supported:
  • Safari 2