Reputation: 57
Given an <input id="foo">
element, I want to call an existing function on blur and pass an anonymous callback to it.
Case 1, simple function call:
function bar(){
alert("I am");
}
$("#foo").blur(bar); //Works fine
Case 2, passing arguments/function:
$("#foo").bind("blur", {func: function(){console.log("I am apple")}}, bar);
function bar(event){
event.data.func(); //Works fine
};
Problem with case 2 is that I'd like to have bar()
as a generic function called by more than blur, in which case I would be passing anonymous function directly, not "baked" into a data object. So ideally like this:
function bar(callback){
//Do stuff
callback();
}
bar(function(){console.log("Hello Earth")}); //Works
$("#foo").blur(bar(function(){console.log("Hello world")})); //Doesn't work
Last line doesn't work as function gets executed directly, but it's an example of what I would like to achieve. I guess I possibly could make some typeof checks in bar()
to determine what I am receiving, but I wanted to ask if there's a cleaner way to pass anonymous function on blur, instead of changing bar()
.
Upvotes: 2
Views: 76
Reputation: 6803
function bar(callback){
//Do stuff
callback();
}
bar(function(){console.log("Hello Earth")}); //Works
$("#foo").blur(bar.bind(this,function(){console.log("Hello world")})); //Will work
Upvotes: 2
Reputation: 1074365
...I wanted to ask if there's a cleaner way to pass anonymous function on blur, instead of changing
bar()
.
Not sure quite what you mean by that, you will have to either change bar
or wrap bar
.
Make bar
a handler generator rather than a direct handler:
function bar(callback) {
return function(e) {
// You could use `e` (the event) here and/or pass it on to the callback
callback();
// You might use the callback's return, e.g.:
// return callback();
// ...if you wanted it to be able to `return false`
};
}
Now, bar
returns an event handler that will call the callback (in addition, presumably, to doing something of its own; otherwise, it's a bit pointless and you'd just pass the callback directly).
Usage:
$("#foo").blur(bar(function(){console.log("Hello world")}));
If you literally mean you don't want to change bar, you'll need to wrap it:
function wrap(f, callback) {
return function() {
// You could call `callback` here instead of later if you like
// Call the original function passing along the `this` and
// arguments we received (`arguments` isn't pseudo-code, it's
// a pseudo-array JavaScript creates for you), get its return value
var retval = f.apply(this, arguments);
// Call the callback
callback();
// Return the original function's return value
return retval;
};
}
If you want to avoid letting errors thrown by callback
to make it to the event mechanism, you can wrap it in a try
/catch
.
Usage:
$("#foo").blur(wrap(bar, function(){console.log("Hello world")}));
Upvotes: 4
Reputation: 28611
Last line doesn't work as function gets executed directly
$("#foo").blur(bar(function(){console.log("Hello world")}));
On the last line you're passing the result of bar
to the blur()
function, not bar itself, it's the same as:
var result = bar(function(){console.log("Hello world")});
$("#foo").blur(result);
The standard method is to wrap this in an anon function:
$("#foo").blur(function() { bar(function(){console.log("Hello world")}) });
This means there are no changes to your other existing functions, as per the question requirement: "instead of changing bar()"
Upvotes: 0
Reputation: 880
function bar(){
alert("I am blur");
}
$("#foo").bind('blur',bar);
Upvotes: 0
Reputation: 12452
Wrap it and return it as an anonymous function:
function bar(callback){
return function() {
callback();
}
}
// direct
bar(function(){console.log("Hello Earth")})();
// as callback
$("#foo").blur(bar(function(){console.log("Hello world")}));
Upvotes: 0