views:

107

answers:

3

I want to apply a click() event to all of the links on a page when the href of that link points to a file with a specific extension. The list of applicable extensions is hovering around 30 and may grow a bit in the future (but will never be more than 100).

My first inclination is to structure the event binding like so:

$("a[href$=avi],
   a[href$=ppt],
   a[href$=rtf],

// ...snip a bunch more of these....

   a[href$=pdf],
   a[href$=xml]").click(function() {
      // Do something
 });

Is this crazy?

+5  A: 

I would select all links and then filter it inside the click function, for example like this:

$('a').click(function() {
    var ext = /[^.]+$/.exec($(this).attr('href'));
    switch(ext) {
        case 'avi':
        case 'ppt':
        ...
        case 'xml':
            // Do something
            break;
    }
});

Saves a lot of traversing and is much prettier also.

The bad thing with your approach is that jQuery probably handles each of your selector independently, so after it finishes the search for the first selector, it completely forgets what else it found and searches the whole document again for the next selector. With this method jQuery only has to search once for all of the links, and using switch-case inside the function is probably so fast you don't have to bother yourself with performance issues.

Tatu Ulmanen
This adds a click handler to all links, though. It's just that it doesn't do anything unless the href matches. A solution that only applies the handler to the matching links would be better. See my filter example.
tvanfosson
@tvanfosson: You're right that this method does some unnecessary binding, but in your method jQuery still has to do some extra parsing and traversing which is always slower than a switch-case. So, performance wise, this method is better.
Tatu Ulmanen
+3  A: 

I'll give you a hint - almost definetly. I did something just like this and it was very painful. I tried another approach, storing the results of each selector in an array and then doing $(array).click() was much faster (especially in IE6/P3 900 mHz)

That said, you should benchmark and find the fastest way for your application. Find an old crappy computer with IE6, or get a VM with IE6, and test the timing in that. Selector tuning (and seeing which are slow and how I can avoid calling them) is my first stop on javascript optimizing.

Tom Ritter
+1 for benchmarking
GloryFish
+2  A: 

I would consider using a filter function rather than a set of selectors:

$('a').filter( function() {
           return $(this).attr('href').match( /(avi|ppt|...|xml)$/ ) != null;
       })
      .click( function() {
           // do something
       });
tvanfosson