Reputation: 2585
I had these lines in my javascript file and it was working fine.
handleInput = function(e) {
var $this = $(this),
id = $this.attr("id");
alert(id);
}
....
something.bind("keyup", handleInput);
Then I decided to delay the input function and added following lines:
handleDelayedInput = function(e) {
setTimeout(handleInput(e), 50);
}
.....
something.bind("keyup", handleDelayedInput);
But now alert(id);
says undefined, because I think I couldn't pass the this to that function.
Am I right? How can I fix? Is there any better way to do that?
Upvotes: 0
Views: 78
Reputation: 23142
Use the apply
function:
var handleDelayedInput = function(e) {
var that = this;
setTimeout(function() {
handleInput.apply(that, [e]);
}, 50);
}
something.bind("keyup", handleDelayedInput); // Assuming something is a
// jQuery object
Here's a working jsFiddle.
Calling handleInput
like this setTimeout(handleInput(e), 50);
will lose the context, so this
won't be what you expect within handleInput
in that case.
Also, setTimeout
should be passed a function, not the result of a function (unless the result is itself a function).
Upvotes: 1
Reputation: 16571
When jQuery calls the event handler it sets the context of the handler function. This isn't the case when handleInput is called in your second piece of code, so this
is set to the default value window
.
You can use apply
or call
to set the context:
handleInput.call(this, e);
The difference between the two is that apply
takes an array of arguments while you can pass the arguments to call
one by one: func.apply(context, arg1, arg2)
.
So your full code would be:
handleInput = function(e) {
var $this = $(this),
id = $this.attr("id");
alert(id);
}
handleDelayedInput = function(e) {
var element = this;
setTimeout(function(){
handleInput.call(element, e);
}, 50);
}
something.bind("keyup", handleDelayedInput);
Note that, since we're using setTimout we need to find a way to pass the element to the timeout handler function. Also, in your code you're using the return value of handleInput(e)
as the handler function - rather than handleInput
.
I agree with Mike though, if you wrote handleInput yourself and you can modify it there's not point in using this
instead of just passing the argument. If you still want to use handleInput as a direct handler somewhere else it would make sense to keep it the way you have it.
Upvotes: 1
Reputation: 71422
That is because you are no longer passing handleInput
any object context like you were when calling it from your jQuery bind method. Personally I would rewrite the whole thing like this:
something.on("keyup", function(e) {
var obj = $(this);
setTimeout(function(obj) {
alert(obj.attr("id");
}, 50);
});
Note the use of on()
instead of bind()
which is now the preferred usage.
Upvotes: 2
Reputation: 23665
You could do it like so:
handleInput = function(e) {
var $this = $(this),
id = $this.attr("id");
setTimeout(function() {alert(id);}, 50);
}
Upvotes: 0