3

Currently, I have a cached variable, $this, on which I'm applying .on to respond to various possible types of behaviour triggers.

$this.on('click','.trigger a',rowTrigger);
$this.on('click','.actions nav a',rowAction);

In the jQuery .on Documentation it doesn't mention if there's a way to combine the above two into a single call. For example, something like this might be nice:

$this.onAny({
    click: [
        {'.trigger a':rowTrigger},
        {'.actions nav a':rowAction}
    ]
});

Is there a way to achieve this kind of statement (e.g. an existing plugin to extend .on)?

UPDATE

Use Case (in the current code, prior to a nice solution):

// Plugin 1:
function addTriggers(){
  $this.find('td:last').append('<span class="trigger"><a href="#"></a></span>');
  return {selector:'.trigger a', event:'click', target: $this, callback: rowTrigger};
}

// Plugin 2:
function addInlineNavigation(){
  $navCode = '...'
  $this.find('td:last').append('<div class="actions">'+$navCode.html()+'</div>');
  return {selector:'.actions nav a', event:'click', target: $this, callback: rowAction};
}
MyStream
  • 2,533
  • 1
  • 16
  • 33
  • To create an array that can be added to by other plugins that want to extend functionality to `$this` when certain events are bound (in my case). An object would also work, but the idea I'm working with is to abstract out the target selector and callback pairs. – MyStream Mar 25 '13 at 10:12
  • http://stackoverflow.com/questions/8462027/jquery-on-method-on-multiple-selectors – sasi Mar 25 '13 at 10:13
  • 1
    This SO reference refers to multiple selectors with a single callback, not multiple selectors with multiple callbacks, but thank you. – MyStream Mar 25 '13 at 10:14

1 Answers1

7

Is there a way to achieve this kind of statement (e.g. an existing plugin to extend .on)?

I'm not aware of one. Would be nearly trivial to write. I'm not seeing much advantage to it, though, compared with chaining:

$this.on('click','.trigger a',rowTrigger)
     .on('click','.actions nav a',rowAction);

But again, the plug-in isn't complicated. Here's an untested rough draft:

jQuery.fn.onAny = function(options) {
    var eventName, eventSpec, eventEntry, selector, i;

    for (eventName in options) {
        eventSpec = options[eventName];
        if (jQuery.isArray(eventSpec)) {
            // Your example, where each event name has an array of objects
            // keyed by selector, where the value is the handler
            for (i = 0; i < eventSpec.length; ++i) {
                eventEntry = eventSpec[i];
                for (selector in eventEntry) {
                    this.on(eventName, selector, eventEntry[selector]);
                }
            }
        }
        else {
            // Assuming just a straight handler here
            this.on(eventName, eventSpec);
        }
    }

    return this;
};
Tim Büthe
  • 62,884
  • 17
  • 92
  • 129
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • +1 for "I'm not seeing much advantage to it" and the chained call. Building a plugin for this is IMO a bad idea. New team members would have to learn what it is etc. – Tim Büthe Mar 25 '13 at 10:18
  • 1
    Hi =) the area where I'm applying this is documented, so this would be a simple thing to learn. E.g. in my case I have an array holding event names (e.g. 'click'), a selector to listen to (e.g. '.trigger a') and the callback (rowTrigger) function name. It functions like pub/sub in some ways, so it's not a steep learning curve, but useful in my particular case! – MyStream Mar 25 '13 at 10:20
  • @TimBüthe: Thanks for fixing that typo! – T.J. Crowder Mar 25 '13 at 10:24
  • @MyStream: do you really need this in more than one place? If not, just iterate your array and attach the handlers using 'on'. If you need it more than once, write a utility function. And if you need it all over the place, make a plugin or refactor your code :-) – Tim Büthe Mar 25 '13 at 10:28
  • I have different functions for admin, account and public areas of a site I'm working on so I was looking to generalise the logic of adding event handlers to a common function or plugin instead of duplicating the logic inline in each file. It's not essential, just wondering and T.J. Crowder's method allows me to write `$( selector ).onAny( behaviourEnhancements );` which is an elegant solution, I think, for this use-case? The code's quite short, but I was 50/50 on making a plugin so thought I'd ask better minds first :) – MyStream Mar 25 '13 at 10:33