Arjan van der Gaag .nl

I’m Arjan van der Gaag and this is my website about me, code, food, photography and more. If you like, we can get in touch.


jQuery custom selectors

I like writing jQuery plugins, so I can separate functionality into distinct units. But applying the plugin sometimes requires some logic I’d rather have in my plugin itself.

Example code

Say I want to create a plugin that creates a lightbox-style image zooming effect. I want to apply it to all links pointing at an image:

<a href="/images/photo1.jpg"><img src="/images/photo1.jpg"></a>

Here’s how I might call my awesome plugin in my main javascript file:

$(function() {
    // One option: create complex inline selectors:
    $('a[href$="jpg"], a[href$="png"]').awesome_plugin();

    // Second option: filtering
    $('a').filter(function() {
        $(this).attr('href').match(/\.(png|gif|jpe?g)$/);
    }).awesome_plugin();
});

These both might work, but they move typical plugin logic to my javascript initializer. That’s not what I want.

Custom selector

The solution is so obvious I wonder why I did not think of it before: write a custom jQuery selector:

$(function() {
    $('a:to_image').awesome_plugin();
});

Awesome: concise and with clear intent. Here’s one way to implement it:

// Somewhere in my plugin
$.expr[':'].to_image = function(obj, index, meta, stack) {
    return $(obj).attr('href').match(/\.(png|gif|jpe?g)$/);
};

Now all the logic is nicely tucked away in my plugin.