问题
This is some rough javascript/jquery/coffeescript that slides in a DIV on the lower part of the page after a delay. I'm working in a rails, so I'm also hitting an endpoint that increments a view counter in the database for a specific slide.
jQuery ->
$("div[data-slide='true']").delay(20000).animate({opacity: 1,right:'+=350'},1350, 'swing');
id = $("div[data-slide='true']").data("slide-id")
$.ajax({url: "http://localhost:3000/firefly/slides/" + id + "/increment", type: "post"});
$("div[data-close='true']").click ->
$("div[data-slide='true']").clearQueue().animate({opacity: 0,right:'-=350'},500, 'easeOutBounce');
I'm aware this isn't the best javascript, I'm really a novice at JS -- but my problem right now is I can't figure out how to delay the ajax call so it only hits the endpoint when the slide is animated in. Right now, it hits the end point and increments the counter when the DOM has finished loading.
回答1:
I don't know or use coffeescript
(thanks God), but you can use the callback of the animation.
Use this overload:
.animate( properties [, duration] [, easing] [, complete]
Put the ajax in the complete
function callback.
回答2:
An alternative answer: In jQuery 1.6+, there's an alternative to passing a callback directly: Get a Promise, and attach the callback to it. That would allow your code to be written more clearly, like so:
var swinging = $("div[data-slide='true']")
.delay(20000)
.animate({opacity: 1,right:'+=350'},1350, 'swing')
.promise();
$("div[data-close='true']").click ->
$("div[data-slide='true']").clearQueue()
.animate({opacity: 0,right:'-=350'},500, 'easeOutBounce');
swinging.done ->
id = $("div[data-slide='true']").data("slide-id")
$.ajax({url: "http://localhost:3000/firefly/slides/" + id + "/increment", type: "post"});
More info on Promises and their advantages can be found in my book, Async JavaScript.
来源:https://stackoverflow.com/questions/10819668/delaying-ajax-call-in-jquery-coffeescript