Thursday, June 4, 2009

jQuery plugin to escape CSS selectors

Sometimes in jQuery you need to find an element(s) using a selector that contains special characters, for instance #, or .. I'm quite baffled that jQuery doesn't include a CSS selector escape function. Not that you should use special characters in your class/id attributes, but hey, sometimes you don't have control over the content.

My escape function uses a couple of neat JavaScript techniques like closures (very, very useful once you get the hang of 'em!) and regular expressions. I use Simon Willison's Escaping regular expression characters in JavaScript Regex extension a lot. For more on closures check out Mark Wubben's Getting Funky With Scopes and Closures.

As an extreme example, say we have something as crazy as:

<div id='#;&,.+*~":!^$[]()=>|/'> Hello World! </div>
We can match that with this jQuery:
$('#' + jQuery.escapeSelector('#;&,.+*~":!^$[]()=>|/'))

Try it out:

Here's the code

/**
 * jQuery static function extensions.
 */
 
jQuery.extend(jQuery, {
  /**
   * Escape all special jQuery CSS selector characters in *selector*.
   * Useful when you have a class or id which contains special characters
   * which you need to include in a selector.
   */
  escapeSelector: (function() {
    var specials = [
      '#', '&', '~', '=', '>', 
      "'", ':', '"', '!', ';', ','
    ];
    var regexSpecials = [
      '.', '*', '+', '|', '[', ']', '(', ')', '/', '^', '$'
    ];
    var sRE = new RegExp(
      '(' + specials.join('|') + '|\\' + regexSpecials.join('|\\') + ')', 'g'
    );

    return function(selector) {
      return selector.replace(sRE, '\\$1');
    }
  })()
});