Sunday, March 11, 2012

when to latch onto elements by class with jQuery

I had an interview question on whether or not I like to grab elements by their classes in jQuery and I asserted that I'd rather use ids. It just seems all too easy for someone else to innocently apply a class to an element unaware that they are also applying some functionality by way of jQuery markup that is present but out-of-sight/out-of-mind. Yet... When would one break this rule?

This weekend at the Dallas Day of Dot Net convention, Scott Hanselman, in his keynote, mentioned that there is an HTML5 input type called datetime which Safari can make sense of but which is out of grasp so far for most browsers.

<input type="datetime" id="foo" name="foo">

 
 

The HTML above (with some other markup surrounding it) is portrayed below in Safari at the left and IE9 at the right. The two browsers show the SAME document.

He suggested letting browsers that can handle the datetime input type display it while using Modernizr to prevent other browsers from just showing a regular input field. He recommended using datepicker instead. The code on his slide looked like this:

$function () {

   if (!Modernizr.inputtypes.datetime) {

      $("input[type='datetime']").datepicker();

   }

});

 
 

It occurred to me that this CSS selector trick would not work for many browsers that did not support selectors. Scott Hanselman, to his credit, suggested it was time to stop worrying about IE6, so perhaps he approached this piece of code under the guise of just getting datepicker to the browsers that were worth caring about. Understandable. Yet... What if we wanted an all-inclusive (down to IE6) solution? I mentioned this is conversation to Justin Pope of Headspring and he thought that a class-based approach was the way to go. I envision him envisioning something like this:

$function () {

   if (!Modernizr.inputtypes.datetime) {

      $(".bar").datepicker();

   }

});

 
 

To make this work, you'd have to decorate all of the datetime fields with the class like so:

<input type="datetime" id="foo" name="foo" class="bar">

 
 

How do we keep another developer from misusing the class? It would be best to keep classes that one uses to empower jQuery manipulations separate from those that one uses to actually style things. In our example, the bar style should do nothing in and of itself. It should not appear in the stylesheet whatsoever. It’s absence would prevent another developer from seeing it in the stylesheet and thinking "Hey, this is a great style to slap on this other thing over elsewhere..." If one did need to apply a style to some or all datetime types, it should probably be independent like so:

<input type="datetime" id="foo" name="foo" class="bar baz">

 
 

The baz class could appear in the stylesheet and have, for example, padding-top: 10px; or whatever else you’d like in it. This creates a separation between classes for jQuery and classes for what classes are intended for (styling). If you are to go down this path, it might also be wise to have a naming convention to distinguish the two as well. (bar and baz aren't the best names)

No comments:

Post a Comment