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');
    }
  })()
});

3 comments:

jaffadan said...

Thank you very much for this post. We had an issue with nested form id's and jQuery. This would also fix any issues with JSF naming conventions and jQuery.

spacepenguin said...

It looks like you forgot @ in your list of specials.

Thank you for the function though! saved me lots of time.

Алексей Аврутин said...

Thank you, just what I need.