9

Here is the code:

$("div").on("click",function(){
       console.log("click");
});
$("div").on("click.plugin", function(){
       console.log("click.plugin");
});
$("button").click(function() {
      $("div").trigger("click!");    
});

and the HTML:

<div>test.</div>
<button >Trigger event according to namespace</button>

When I run the code under jQuery 1.8.3, it works. When I click button, it logs click in the console.

But when I change to jQuery 1.9.1, nothing happens when I press the button. It seems like the exclamation mark doesn't work anymore in 1.9.1.

I can't find this change in the 1.9 upgrade guide. Does anybody know why?

Tomalak
  • 332,285
  • 67
  • 532
  • 628
James
  • 157
  • 1
  • 6
  • 5
    Never seen that before. What is it supposed to do? – JJJ May 09 '13 at 10:00
  • @juhana never seen that either. Docs say it should trigger only not-namespaced handlers. – kapa May 09 '13 at 10:04
  • 1
    @bažmegakapa Where did you read in Docs? Can you point that out to me? – Starx May 09 '13 at 10:08
  • I can find only non-official mentions. Undocumented feature? – JJJ May 09 '13 at 10:13
  • 1
    http://docs.jquery.com/Events/trigger – kapa May 09 '13 at 10:14
  • possible duplicate of [trigger event with jquery without a namespace](http://stackoverflow.com/questions/13691402/trigger-event-with-jquery-without-a-namespace) – Starx May 09 '13 at 10:26
  • @bažmegakapa - please note: as stated on the docs.jquery.com front page: *The references on docs.jquery.com are obsolete. Please see http://api.jquery.com for up-to-date documentation.* – Spudley May 09 '13 at 11:15
  • @Spudley You're right, Google fooled me... – kapa May 09 '13 at 11:18

2 Answers2

5

Use .$ instead of !

$("button").click(function() {
      $("div").trigger("click.$");    
});

Demo [Credits: Tim B James]

Starx
  • 77,474
  • 47
  • 185
  • 261
  • @bažmegakapa, The funny thing about that page was that it was linked to another SO question [here](http://stackoverflow.com/questions/13691402/trigger-event-with-jquery-without-a-namespace). Ha ha. But seen the demo and it works. – Starx May 09 '13 at 10:26
  • @TimBJames, Thanks I will add that to the answer. – Starx May 09 '13 at 10:30
  • 2
    @bažmegakapa, Seems like a undocumented hack. Cannot find it anywhere and am too lazy to dig the source :( – Starx May 09 '13 at 10:36
  • 1
    jQuery is not using regex to find the event name. This only happens to work by accident. – Tomalak May 09 '13 at 11:06
  • @Tomalak, Thank you for the explanation. I better remove that from the answer then :) – Starx May 09 '13 at 11:56
  • 1
    The reason why appending `'.$'` works is because of the `if ( type.indexOf(".") >= 0 )` part (see my answer). Since there is no event namespace `'$'` it seems as if only `click` was triggered. – Tomalak May 09 '13 at 12:06
4

This is how jQuery 1.8.3 looks like:

trigger: function( event, data, elem, onlyHandlers ) {

    // Don't do events on text and comment nodes
    if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {
        return;
    }

    // Event object or event type
    var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType,
        type = event.type || event,
        namespaces = [];

    // focus/blur morphs to focusin/out; ensure we're not firing them right now
    if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
        return;
    }

    if ( type.indexOf( "!" ) >= 0 ) {
        // Exclusive events trigger only for the exact event (no namespaces)
        type = type.slice(0, -1);
        exclusive = true;
    }

    if ( type.indexOf( "." ) >= 0 ) {
        // Namespaced trigger; create a regexp to match event type in handle()
        namespaces = type.split(".");
        type = namespaces.shift();
        namespaces.sort();
    }

    // ...

Notice the "Exclusive events trigger only for the exact event" section.

And this is jQuery 1.9.1:

trigger: function( event, data, elem, onlyHandlers ) {
    var handle, ontype, cur,
        bubbleType, special, tmp, i,
        eventPath = [ elem || document ],
        type = core_hasOwn.call( event, "type" ) ? event.type : event,
        namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];

    cur = tmp = elem = elem || document;

    // Don't do events on text and comment nodes
    if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
        return;
    }

    // focus/blur morphs to focusin/out; ensure we're not firing them right now
    if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
        return;
    }

    if ( type.indexOf(".") >= 0 ) {
        // Namespaced trigger; create a regexp to match event type in handle()
        namespaces = type.split(".");
        type = namespaces.shift();
        namespaces.sort();
    }

    // ...

Here the entire section is missing (it's also not in the omitted bit).

It seems as if jQuery has dropped support for this feature. The variable exclusive has been removed from the whole source.

Looking at the source of version 1.9.1 I don't see a way for you to get the desired functionality without resorting to hacks.

Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • Thanks for all you guys's answers, and do we have jQuery engineers in this website, maybe we can tell them to put this change in jQuery 1.9.1 upgrade guide. – James May 09 '13 at 14:21
  • 1
    jQuery has [a bug tracking system](http://bugs.jquery.com/). Open a ticket and see what happens. – Tomalak May 09 '13 at 14:25
  • 1
    Thanks, Tomalak, I've already post the issue on tracking system and got the resonse, they will add it in upgrade guide. Here is the link: http://bugs.jquery.com/ticket/13873 – James May 10 '13 at 01:42
  • On this [line](https://github.com/jquery/jquery/blob/master/src/event.js#L244) jQuery seems to be using regex to match the event names isn't it? – Starx May 10 '13 at 01:50
  • It seems like it, but there is no documentaion for it. – James May 10 '13 at 01:57
  • @user2301368, The hack I posted should be enough to solve your problem until they add it on their next upgrade. Good Luck :) – Starx May 10 '13 at 03:19