2016-07-16 3 views
2

У меня есть яваскрипт функция, которая идет как это:Javascript ждать до функции завершения

$(document).keydown(function(e) { 
    switch(e.which) { 
     case 38: 
      moveUp(); 
      break; 
     case 40: 
      moveDown(); 
      break; 
    } 
}); 
function moveDown() { 
    $('element').animate({top: "100%"}, {duration: 1000 }); 
} 
function moveUp() { 
    $('element').animate({top: "-100%"}, {duration: 1000 }); 
}   

Моим вопрос заключается в том, как бы создать задержку в функции keydown, что сообщает ему, что он должен подождать, пока функции moveUp()/movedown() закончен, прежде чем снова вызвать функцию без создания очереди?

Благодарим вас за консультацию, кстати, я не могу использовать setTimeout, потому что это вызовет задержку при каждой начальной функции.

+1

https://api.jquery.com/delay/ возможно? – mplungjan

+1

Выполните ['setTimeout'] (https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout) за 1 секунду/секундомер? – Shubh

+0

Что вы хотите, если пользователь нажимает вверх/вниз во время анимации? Должна ли их нажатие нажать кнопку после анимации? Или его следует игнорировать? – smarx

ответ

3

Это должно помочь вам, я использовал полную функцию анимации, чтобы выполнить следующее действие, как только оно закончит анимацию.

var isAnimating = false; 
var callAfterFinish = undifined; 
$(document).keydown(function(e) { 
    switch(e.which) { 
     case 38: 
      moveUp(); 
      break; 
     case 40: 
      moveDown(); 
      break; 
    } 
}); 
function moveDown() { 
    if(!isAnimating){ 
     $('element').animate({top: "100%"}, {duration: 1000 },function(){ 
      if(!callAfterFinish) { 
       callAfterFinish(); 
       callAfterFinish = undifined; 
      } 
      isAnimating = false; 
     }); 
     isAnimating = true; 
    } else if(!callAfterFinish) { 
     callAfterFinish = moveDown; 
    } 
} 
function moveUp() { 
    if(!isAnimating){ 
     $('element').animate({top: "-100%"}, {duration: 1000 },function(){ 
      if(!callAfterFinish) { 
       callAfterFinish(); 
       callAfterFinish = undifined; 
      } 
      isAnimating = false; 
     }); 
     isAnimating = true; 
    } else if(!callAfterFinish) { 
     callAfterFinish = moveUp; 
    } 
}   
0

Я могу предложить вам установить атрибут данных.

animate имеет полный обратный вызов. Поэтому перед запуском анимации вы можете установить атрибут в false, и когда анимация будет завершена, вы можете сбросить значение true.

Этот атрибут можно протестировать в событии keydown, чтобы решить, имеет ли он право продолжать.

$(function() { 
 
    // set the data attribute to true 
 
    $(document).data('isAnimateCompleted', true); 
 

 
    $(document).keydown(function(e) { 
 
    // if false return 
 
    if ($(document).data('isAnimateCompleted') == false) { 
 
     return; 
 
    } 
 
    switch(e.which) { 
 
     case 38: 
 
     moveUp(); 
 
     break; 
 
     case 40: 
 
     moveDown(); 
 
     break; 
 
    } 
 
    }); 
 
    function moveDown() { 
 
    // before starting set to false 
 
    $(document).data('isAnimateCompleted', false); 
 
    $('#element').animate({top: "100px"}, 1000, function() { 
 
     // when completed set to true 
 
     $(document).data('isAnimateCompleted', true); 
 
    }); 
 
    } 
 
    
 
    function moveUp() { 
 
    $(document).data('isAnimateCompleted', false); 
 
    $('#element').animate({top: "0px"}, 1000, function() { 
 
     $(document).data('isAnimateCompleted', true); 
 
    }); 
 
    } 
 
});
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script> 
 

 
<div id="element" style="position: fixed;top: auto;">This is an element</div>

Другая возможность состоит в том, чтобы использовать селектор JQuery animated, чтобы проверить, является ли анимация в процессе, избегая при всех глобальных переменных.

3

Предполагая, что нажатия клавиш не будут иметь никакого эффекта во время анимации, это должно помочь. Когда анимация вот-вот начнется, я установил переменную с именем inProgress в true. Я вернул его в false в обработчик для анимации. В обработчике keydown я проверяю этот флаг, и если анимация выполняется, я игнорирую ключ.

var position = 50; 
 
var inProgress = false; 
 

 
function move() { 
 
    inProgress = true; 
 
    $('#box').animate({ top: position + 'px', duration: 1000 }, function() { 
 
    inProgress = false; 
 
    }); 
 
} 
 

 
$(document).keydown(function(e) { 
 
    if (inProgress) { 
 
    return; 
 
    } 
 
    switch(e.which) { 
 
    case 38: 
 
     e.preventDefault(); 
 
     position -= 10; 
 
     move(); 
 
     break; 
 
    case 40: 
 
     e.preventDefault(); 
 
     position += 10; 
 
     move(); 
 
     break; 
 
    } 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="box" style="position:absolute;top:50px;background-color:blue;width:50px;height:50px"></div>

3

Вот простое решение.

var flag = true; 
 
$(document).keydown(function(e) { 
 
    if(flag == true){ 
 
    \t switch (e.which) { 
 
     case 38: 
 
     moveUp(); 
 
     break; 
 
     case 40: 
 
     moveDown(); 
 
     break; 
 
    } 
 
    } 
 
    
 
}); 
 

 

 

 
function moveDown() { 
 
    $('#elem').animate({ 
 
    top: "100px" 
 
    }, { 
 
    duration: 1000, 
 
    start: function(){ flag=false; }, 
 
    complete: function(){flag=true; } 
 
    }); 
 
} 
 

 
function moveUp() { 
 
\t 
 
    $('#elem').animate({ 
 
    top: "0px" 
 
    }, { 
 
    duration: 1000, 
 
    \t start: function(){ flag=false; }, 
 
    complete: function(){flag=true; } 
 
    }); 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div style="background: green; width: 100px; height: 100px; position:absolute;" id="elem"> 
 

 
</div>

Смежные вопросы