views:

202

answers:

3

Hello everyone. What would be the best way to send a message to the click event to find out from where it was called?.

$("#mybutton").click(function(ev){

   if (called from funcion One or Two){
     //my code
   }

});

funOne = function(){
  $("#mybutton").click();   
};

funTwo = function(){
  $("#mybutton").click();   
};

EDIT:

on a "trigger" I have a small solution, but depends on all implement the parameter "data"

EDIT (II):

My solution based on a '@Roatin Marth' Answer.

jQuery.fn.trigger = function(event, data) {

    var type = event.type || event,
        expando = "jQuery" + (+new Date);

    event = typeof event === "object" ?
    // jQuery.Event object
        event[expando] ? event :
    // Object literal
        jQuery.extend(jQuery.Event(type), event) :
    // Just the event type (string)
        jQuery.Event(type);

    if (!event.caller) {
        var xcaller = "";
        try {
            xcaller = arguments.callee.caller;
        } catch (ex) { };
        event.caller = xcaller;
    }

    return this.each(function() {
        jQuery.event.trigger(event, data, this);
    });
};


jQuery.fn.click = function(fn) {

    var returned = null;

    if (fn) {
        returned = this.bind('click', fn)
    } else {
        var event = jQuery.Event('click'), xcaller = "";
        try {
            xcaller = arguments.callee.caller;
        } catch (ex) { };
        event.caller = xcaller;
        returned = this.trigger(event);
    }

    return returned;
};
A: 
Reigel
A: 

You are looking for arguments.callee. Now form javascript 1.4 it was deprecated.

See here for more details.

Teja Kantamneni
jQuery to be the manager for the event, the caller is a jQuery method
andres descalzo
@Teja: this doesn't work. `click()` doesn't actually call the handler directly. It goes through an entire jQuery internal code path. `arguments.callee.caller` is meaningless as is by the time the handler is reached.
Roatin Marth
Hmm, yes I didn't think of that.
Teja Kantamneni
+3  A: 

You can pass data when triggering an artificial event, the catch is you can't use the shortcut functions like click(), but instead use trigger directly:

$("#mybutton").tigger('click', ['One', 'Two']);

Click handler:

$("#mybutton").click(function(ev, customArg1, customArg2) {
  customArg1; // "One"
  customArg2; // "Two"
})

Seeing as how .click() is just a shortcut to .trigger('click') anyway, you don't lose anything by doing it this way, just more keystokes ;)


Edit addressing comments:

the system is already written and is large enough to make a change in all scripts

In this case you might need to hack jQuery to capture arguments.callee.caller and pass it along to your handler:

jQuery.fn.click = function(fn) {
  return fn ? this.bind(name, fn) : this.trigger(name, [arguments.callee.caller]);
};

With that patch, code that calls .click() directly will now pass their calling function scope info on to your click handler, which now can do this:

$("#mybutton").click(function(ev, caller) {
   if (caller === funOne || caller === funTwo){
     //my code
   }
});

If what this says is true, then arguments.callee.caller is not going to be reliable in the future, but then, a hack is called a hack for a reason ;)

Roatin Marth
yes, I saw this option, but the system is already written and is large enough to make a change in all scripts
andres descalzo