0

I misread what @goddfree had posted below. His solution works perfectly, with the only change I made being that setting isDone back to true is placed in the animate function's callback like so:

$.when($('#carousel_ul_' + unique_id + ' li:last').clone().insertBefore('#carousel_ul_' + unique_id + ' li:first'), $('#carousel_ul_' + unique_id).css('left', '-=' + displace_width + 'px')).done($('#carousel_ul_' + unique_id + ':not(:animated)').animate({left: '+=' + scroll_width + 'px'}, 400, function(){$('#carousel_ul_' + unique_id + ' li:last').remove(); is_done = true; }));

This is a really elegant solution, thank you @goddfree

1 Answers1

0

HTML anchor tags have onClick events too. Did you try something like this? From here you can should be able to use the solutions that you found.

<a href="#" onclick='carousel("left", 99335)'><!--stuff here--></a>

Update:

I think this may be what you are looking for. Say you have three buttons (I'm just making up carousel parameters, I have no clue what they mean):

<a href="#" onclick='carousel("left", 99335)'>Button 1</a>
<a href="#" onclick='carousel("right", 69235)'>Button 2</a>
<a href="#" onclick='carousel("left", 91235)'>Button 3</a>

We add a variable called isDone to check if any processes are running or not. Modify the carousel function like so (I explain the modifications using comments):

//isDone is initially set to true, because nothing is running.
var isDone = TRUE;

function carousel(direction, unique_id) {
//First of all, we can only execute the function is isDone is true. So we check for that:
if(isDone) {
//This implements the moment the function is called. We now know that it is currently in progress.
isDone = FALSE;
//This is the same as you had before
if (direction == 'right') {
    $(document).ready(function(){
        var displace_width = $('#carousel_ul_' + unique_id + ' li:last').outerWidth(true);
        var scroll_width = $('#carousel_ul_' + unique_id + ' li:first').outerWidth(true);
        //Here we set isDone equal to true when the .done is called:
        $.when($('#carousel_ul_' + unique_id + ' li:last').clone().insertBefore('#carousel_ul_' + unique_id + ' li:first'), $('#carousel_ul_' + unique_id).css('left', '-=' + displace_width + 'px')).done(isDone = TRUE; $('#carousel_ul_' + unique_id + ':not(:animated)').animate({left: '+=' + scroll_width + 'px'}, 400, function(){$('#carousel_ul_' + unique_id + ' li:last').remove(); }));
    });
} else {
    $(document).ready(function(){
        var displace_width = $('#carousel_ul_' + unique_id + ' li:first').outerWidth(true);
        var scroll_width = $('#carousel_ul_' + unique_id + ' li:nth-child(2n)').outerWidth(true);
        //Same thing here
        $.when($('#carousel_ul_' + unique_id + ' li:first').clone().insertAfter($('#carousel_ul_' + unique_id + ' li:last'))).done(isDone = TRUE; $('#carousel_ul_' + unique_id + ':not(:animated)').animate({left: '-=' + scroll_width + 'px'}, 400, function(){$('#carousel_ul_' + unique_id + ' li:first').remove(); $('#carousel_ul_' + unique_id).css('left', '+=' + displace_width + 'px'); }));
    });
}
}
//If isDone is not true, then we tell the user that and don't execute anything:
else {
    alert("Not so fast! There is a process currently in progress.");
}
}

This way, because all of the buttons call the same carousel function, they will only be executed if isDone is set to true. Otherwise, the user will get an error alert and nothing will happen.

Charles
  • 4,372
  • 9
  • 41
  • 80
  • More specifically, I can find solutions that would be usable if I give each such link an unique ID. (See following link for one such example.) I just wanted to see if anyone had a better solution before I go generating IDs via PHP for all of the links, which seems kind of rube goldberg-y to me (example: http://stackoverflow.com/questions/16715075/preventing-multiple-clicks-on-button) – Jargon Scott Nov 24 '13 at 23:06
  • Forgive me if I'm not fully understanding your problem, but can you use the solution that was suggested in the link you posted in which the button is disabled for a short period of time after it is clicked? – Charles Nov 24 '13 at 23:11
  • The solutions I've seen work by disabling a specific calling button or link. This function is called numerously throughout the page, so it would require some contortions to disable every link that calls it and then to re-enable those links after some amount of time has elapsed. I guess that might be workable, but I thought I'd see if someone else has a better solution first. – Jargon Scott Nov 24 '13 at 23:31
  • As far as I understand, the problem with calling the function twice in rapid succession is duplicates. So why not just only disable the specific button that the user clicked? They're going to take a second or two to move the cursor from one button to another. – Charles Nov 24 '13 at 23:33
  • If the user double clicks any of the buttons that call this function, duplicates are created. Although $.when( ... ).done( ... ) achieves the effect of making sure the duplication of the list item and accompanying position shift are finished before proceeding with the scrolling animation, it doesn't prevent the user from double clicking and initiating the function twice in rapid succession. I basically just need to know if there's some way ot saying: if (this function isn't already in the middle of doing its thing) { ... } – Jargon Scott Nov 24 '13 at 23:44
  • I thought this would work, but no dice: `var is_complete = true; function carousel(direction, unique_id) { if (is_complete) { is_complete = false; (do stuff) } setTimeout(function() { is_complete = true; }, 1000); }` – Jargon Scott Nov 25 '13 at 00:22