Reputation: 3869
I have this very simple jQuery function:
$(".milestone-in-tree").live({
mouseenter: function() {
setTimeout(
$.ajax({
type: "GET",
url:"/projects/pmnodes/" + $(this).data("pmnode") + "/addbuttons.js"
}),5000)
},
mouseleave: function() {
$(".grid-btn").delay(800).remove();
}
});
I want to make it wait 5 secs before sending the AJAX request to the server but it doesn't wait, it just sends it right away. Why?
UPDATE:
Thank you for all the feedbacks. I changed the function as it is suggested in all the answers:
$(".milestone-in-tree").live({
mouseenter: function() {
var node = $(this).data("pmnode")
setTimeout(function() {
$.ajax({
type: "GET",
url:"/projects/pmnodes/" + node + "/addbuttons.js"
}),5000});
},
mouseleave: function() {
$(".grid-btn").delay(800).remove();
}
});
But I still get no delay. Is there something I misunderstood? PS: I created the node variable because, for a reason I ignore, $(this) is not accessible anymore inside the SetTimeout anonymous function.
UPDATE 2
Finally, I could manage to get the delay but I realized that the request was still sent to the server after the delay, even if the mouseleave event had been triggered in between...
I could find a workaround. It is totally different. The delay doesn't work anymore but the ajax requests are aborted on mouseleave events, which is what I really needed. For the ones who might be interested, this is the code:
var button_request;
$(".milestone-in-tree").live({
mouseover: function() {
var node = $(this).data("pmnode");
button_request = $.ajax({
type: "GET",
url:"/projects/pmnodes/" + node + "/addbuttons.js"
});
setTimeout(function() {button_request;},5000)
},
mouseleave: function() {
if (button_request) {
button_request.abort();
button_request = null;
}
$(".grid-btn").remove();
}
});
Of course the setTimeout could be removed (as it doesn't work...) but I leave it for clarity.
Thanks everyone.
Upvotes: 4
Views: 9936
Reputation: 92893
Try this:
$(".milestone-in-tree").live({
mouseenter: function() {
var pmnode = $(this).data("pmnode"); // cache the data in a variable
setTimeout( function() { // this function(){...} wrapper is necessary
$.ajax({
type: "GET",
url:"/projects/pmnodes/" + pmnode + "/addbuttons.js"
})
},5000)
},
...
The first argument of a setTimeout()
call needs to be either a string (which you really, really shouldn't do) or a self-contained function object.
By putting $.ajax(...)
there instead, you're telling JavaScript to (1) run it immediately and (2) set the first argument as whatever the ajax function returns -- which, according to the docs, is a jqXHR object which setTimeout
can't do anything with.
Just get in the habit of putting an anonymous function(){...}
as the first argument of setTimeout()
or setInterval()
every time you use it, and you'll be fine.
Upvotes: 7
Reputation: 14747
setTimeout()
either accepts a string of Javascript code which it eval
s (very bad practice, might I add), or a function reference that it calls after a specified time.
What you're doing here is neither --- you're calling a function as a first parameter to setTimeout()
. Because of that, it doesn't wait.
You want:
setTimeout(function () {
$.ajax({});
}, 5000);
It's like the difference between:
setTimeout(foo, 1000);
and
setTimeout(foo(), 1000);
Upvotes: 6
Reputation: 382606
You are calling it straight away, put it in function callback:
setTimeout( function() {
$.ajax({
type: "GET",
url:"/projects/pmnodes/" + $(this).data("pmnode") + "/addbuttons.js"
})
} ,5000)
Upvotes: 2
Reputation: 38345
You're calling the $.ajax()
function, and passing whatever is returned by that call, to setTimeout()
. You need to wrap it in an anonymous function:
setTimeout(function() {
$.ajax({
type: "GET",
url:"/projects/pmnodes/" + $(this).data("pmnode") + "/addbuttons.js"
})
},5000);
Upvotes: 5
Reputation: 4308
The code you are passing in is actually being executed, if you want to run code inside the first argument you need to wrap it in a function:
$(".milestone-in-tree").live({
mouseenter: function() {
setTimeout(
function(){
$.ajax({
type: "GET",
url:"/projects/pmnodes/" + $(this).data("pmnode") + "/addbuttons.js"
}),5000);
}
},
mouseleave: function() {
$(".grid-btn").delay(800).remove();
}
});
Upvotes: 1
Reputation: 103338
Wrap in an anonymous function:
setTimeout(function(){
$.ajax({
type: "GET",
url:"/projects/pmnodes/" + $(this).data("pmnode") + "/addbuttons.js"
});
},5000)
Upvotes: 2