views:

11173

answers:

4

I have this bit of javascript written with jQuery 1.2.5. It's contained inside the main function() of a plugin that I wrote. The plugin is a horizontal gallery scroller very similar to jCarousel. It does alot of auto calculating of widths and determines how many to scroll based on that and the size of the images, which is what all the calculations are that are going on.

What my question is, how do I prevent this from firing off before a previous execution is finished. For instance, if I get a little click happy and just frantically mash down on .digi_next. Things don't go so well in the UI when that happens and I'd like to fix it :) I thought the answer might lie in queue, but all my attempts at using it haven't turned out anything worthwhile.

 var self = this;
 $(".digi_next", this.container).click(function(){

  var curLeft = $(".digi_container", self.container).css("left").split("px")[0];
  var newLeft = (curLeft*1) - (self.containerPad + self.containerWidth) * self.show_photos;

  if (newLeft < ((self.digi_gal_width - (self.containerPad + self.containerWidth) * self.show_photos)) * -1) {
   newLeft = ((self.digi_gal_width - (self.containerPad + self.containerWidth) * self.show_photos)) * -1;
  }

  $(".digi_container", self.container).animate({
   left: newLeft + "px"
  }, self.rotateSpeed);
 });

Thanks!

+1  A: 

Since JavaScript functions calls are asyncronus, you can pass as a in parameter a callback function that's called when the previous call ends (same for errors).

You can pass the function you wrote in this post as the callback for the function that fire before.

Hope this helps.

Regards

Davide Vosti
+9  A: 

Just use a global busy flag. When you enter your click handler, check it, and only proceed if it's false. Immediately set it to true, and then set it back to false when the animation ends. JavaScript is single-threaded, so there is no race condition to worry about.

var busy = false;
$("...").onclick(function() {
    if (busy) return false;
    busy = true;
    $("...").animate(..., ..., ..., function() {
        busy= false;
    });
    return false;
});
Jim
+4  A: 

Take a look at jQuery UI. Specifically the effects-part of the plug in. I use the slide-effect on my personal website (click on the arrows at the sides of the boxes).

I prevent users triggering the effect more than once - before the effect has ended - with the one event-handler and a callback function.

Here's the source-code

roosteronacid
+2  A: 

As an alternative to the afformentioned global flag, you could assign the value to the DOM element, that way enabling multiple elements on the page to have the same behaviour:

$("...").onclick(function(el) {
    var self = el;
    if (self.busy) return false;
    self.busy = true;
    $("...").animate(..., ..., ..., function() {
        self.busy= false;
    });
    return false;
});
roryf