Как с помощью jQuery убедиться, что функция завершит работу перед тем, как снова выполнить ту же функцию? - PullRequest
2 голосов
/ 17 августа 2010

Итак, у меня есть функция, которая выполняется по событию .click (). Я хочу знать, как я могу убедиться, что функция не запустится до завершения первого запуска? Таким образом, если пользователь щелкнет 3 раза, функция будет запущена 3 раза, но запуск run1 завершится до запуска run2.

Я думал что-то вроде .queue (), но не уверен, как это реализовать.

$(document).ready(function(){

    var numTabs = 10;
    var lastTab = numTabs;
    var currentClass;
    var newClass;

    // Portfolio Gallery

    $('.leftArrow').click(function () {
        $(this).queue(function () {
            // Moves Main 1-5 across
            for (i=1;i<=4;i++) {
                $('#main'+i).animate({'left': '+=229px'}, 'slow');
                $('#main'+i).removeAttr('style');
            }
            $('#main5').removeAttr('style');

            // Removes the Main Classes
            for (i=1;i<=5;i++) {
                $('#main'+i).removeClass('main'+i);
            }

            // Removes the active class from Main3
            $('#main3').removeClass('active');

            // Sets the New Main 1-5 IDs
            for (i=1;i<=5;i++) {
                currentClass = $('#main'+i).attr('class');
                currentClass = currentClass.substr(2);
                newClass = currentClass - 1;
                if (newClass == 0) {
                    newClass = lastTab;
                }
                $('.ex'+newClass).attr('id', 'main'+i);
            }

            // Sends Old Main 5 to the Stack
            if (newClass == lastTab) {
                newClass = 0;
            }
            $('.ex'+(newClass + 1)).removeAttr('id').addClass('theStack');

            // Reassigns the Main CLASSes
            for (i=1;i<=5;i++) {
                $('#main'+i).addClass('main'+i);
            }

            // Moves New Main 1 from Stack to Main 1 position
            $('#main1').removeClass('theStack');

            //Sets Main 3 as the new focus
            $('#main3').addClass('active');

            $(this).dequeue();
        });
    });
});


<div class="pMainHide">
    <div class="pMainShow">
        <div class="ex1 active main3" id="main3"><a href="images/image1.jpg">Image1</a></div>
        <div class="ex2 main4" id="main4"><a href="images/image2.jpg">Image2</a></div>
        <div class="ex3 main5" id="main5"><a href="images/image3.jpg">Image3</a></div>
        <div class="ex4 theStack"><a href="images/image4.jpg">Image4</a></div>
        <div class="ex5 theStack"><a href="images/image5.jpg">Image5</a></div>
        <div class="ex6 theStack"><a href="images/image6.jpg">Image6</a></div>
        <div class="ex7 theStack"><a href="images/image7.jpg">Image7</a></div>
        <div class="ex8 theStack"><a href="images/image8.jpg">Image8</a></div>
        <div class="ex9 main1" id="main1"><a href="images/image9.jpg">Image9</a></div>
        <div class="ex10 main2" id="main2"><a href="images/image10.jpg">Image10</a></div>
    </div>
</div>

Извините, если это слишком большой пост, я раньше не использовал Stack Overflow, и это моя первая реальная попытка использования jQuery.

При необходимости можно добавить CSS ...

Ответы [ 3 ]

2 голосов
/ 17 августа 2010

Проблема заключается в том, что каждая итерация анимации связана с новым элементом.Затем идентификаторы элементов меняются, и анимация помещается в очередь новых элементов.Таким образом, вы попадаете в ситуацию, когда новые элементы запускают анимацию в своей очереди до завершения предыдущей анимации. JavaScript / jQuery не останавливает выполнение скрипта во время анимации.

Для этого jQuery предоставляет параметр callback в .animate() метод.Обратный вызов выполняется после анимация завершена.Я попытался воспользоваться этим, чтобы заставить исполнение желаемым образом.

Решение:

Это все еще использует решение, которое я предоставил ниже, только что реализованное в немногопо-другому.

$(document).ready(function(){
var numTabs = 10;        
var lastTab = numTabs;        
var currentClass;        
var newClass;        
var count = 0; // counter for myCallback
var executing = false;
var myQueue = 0;    
// Portfolio Gallery        

$('.leftArrow').click(doAnimate); // call a named function

function doAnimate(){
    if(!executing){
        executing = true;         
        // Moves Main 1-5 across  <- you are only moving 1-4 here      
        for (i=1;i<=4;i++) {                    // Add Callback--v    
            $('#main'+i).animate({'left': '+=229px'}, 'slow', myCallback);       
            $('#main'+i).removeAttr('style');        
        }        
        $('#main5').removeAttr('style');        

        // Removes the Main Classes        
        for (i=1;i<=5;i++) {        
            $('#main'+i).removeClass('main'+i);        
        }        

        // Removes the active class from Main3        
        $('#main3').removeClass('active');        

        // Sets the New Main 1-5 IDs        
        for (i=1;i<=5;i++) {        
            currentClass = $('#main'+i).attr('class');        
            currentClass = currentClass.substr(2);        
            newClass = currentClass - 1;        
            if (newClass == 0) {        
                newClass = lastTab;        
            }        
            $('.ex'+newClass).attr('id', 'main'+i);        
        }        

        // Sends Old Main 5 to the Stack        
        if (newClass == lastTab) {        
            newClass = 0;        
        }        
        $('.ex'+(newClass + 1)).removeAttr('id').addClass('theStack');        

        // Reassigns the Main CLASSes        
        for (i=1;i<=5;i++) {        
            $('#main'+i).addClass('main'+i);        
        }        

        // Moves New Main 1 from Stack to Main 1 position        
        $('#main1').removeClass('theStack');        

        //Sets Main 3 as the new focus        
        $('#main3').addClass('active');        

    } else {
        myQueue++;
    }   
}
function myCallback(){
    count++;
    if(count == 4){ // needs to be the same as your animate for loop
        count = 0;
        executing = false;
        if(myQueue == 0) return;
        myQueue--;
        doAnimate();
    }
}
});           

Я пошел с именованной функцией, чтобы упростить повторный вызов функции doAnimate().

Предыдущий пост ниже:


Рекурсия и некоторые логическая логика выполнят именно то, что вы просите.

Попробуйте это:

var queue = 0;
var executing = false; 

$('.leftArrow').click(function () { 
    if (!executing) { 
        executing = true; 
        // Animation 
        executing = false;
        if(queue == 0) return;
        queue--;
        arguments.callee();
    } else { 
        queue++;
    } 
}); 
  • В любое времяВаша анимация работает, queue будет увеличиваться на 1.
  • В любое время queue не 0, уменьшение queue, тогда
  • arguments.callee() вызовет вашу анонимную функцию (это рекурсия ).Как и при использовании $(this) для вызова функций.
1 голос
/ 17 августа 2010

Это на тебе. Вы должны создать некоторую boolean логику или отключить / включить кнопку.

var block = false;
$('.leftArrow').click(function(){
    if(!block){
        block = true;
        // do lots of stuff
        block = false;            
    }
});

Возможно, даже лучше использовать callback из метода анимации (в jQuery). Как

$('.leftArrow').click(function(){
    var $this = $(this);

    $this.attr('disabled', 'disabled');
    $('somelement').fadeOut('slow', function(){
       $this.removeAttr('disabled');    
    });
});
1 голос
/ 17 августа 2010

Может быть, это может помочь вам ...

var executing = false;
$('.leftArrow').click(function () {
    if (!executing) {
      executing = true;
      // Execute animation and what not here.
      executing = false;
    } else {
      // just wait?
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...