2010-05-21 2 views
4

У меня есть следующая функция, которая при вызове выводит сообщение пользователю определенное количество времени (5 секунд в моем случае). В течение этого «периода», если я снова вызову функцию, чтобы отобразить другое сообщение, она должна быть скрыта, а затем снова появиться с новым сообщением еще на 5 секунд.Как запустить/остановить/перезапустить анимацию jQuery

Что происходит с моим кодом ниже, я вызываю функцию для отображения сообщения. Затем, скажем, на 4-й секунде, я вызываю его снова, чтобы отобразить другое сообщение, новое сообщение отображается в течение 1 секунды.

Мне нужно как-то - время, но не могу понять, как это сделать. Пробовал останавливать анимацию, проверяя, был ли элемент видимым и скрывал его, если это было, и многое другое. Я считаю, что решение является простой проблемой цепочки, но не может понять это правильно. Поэтому любая помощь будет оценена!

function display_message(msgType, message) { 

    var elem = $('#ur_messagebox'); 

    switch (msgType) { 
     case 'confirm': 
      elem.addClass('msg_confirm'); 
      break; 

     case 'error': 
      elem.addClass('msg_error'); 
      break; 
    } 

    elem.html(message); 
    elem.show().delay(5000).fadeOut(1000); 
} 

заранее спасибо ...

ответ

6

Одним словом, вы не можете использовать .delay() для чего хотите. Это просто оболочка для setTimeout() на следующий элемент очереди, you can see the source here, важная часть:

return this.queue(type, function() { 
     var elem = this; 
     setTimeout(function() { 
      jQuery.dequeue(elem, type); 
     }, time); 
    }); 

Так что это просто очередями в setTimeout(), который при выполнении dequeues следующего элемента в очереди и выполняет его. Так что же происходит в вы добавили задержку, и даже с .stop(true) или .clearQueue(), когда вы в очередь .fadeOut() потом вы добавив, что спиной к жеfx очереди, поэтому, когда что setTimeout() заканчивается за 5 секунд, это захват новый увядает вас в очереди и выполняет его.

Вам нужно setTimout() и очистить его вручную, так как ядро ​​Jquery не имеет такой встроенный, что-то вроде этого:

function display_message(msgType, message) { 
    var mb = $('#ur_messagebox') 
      .addClass(msgType === 'confirm' ? 'msg_confirm' : 'msg_error') 
      .html(message) 
      .stop(true, true).fadeIn(); 
    if(mb.data('delay')) clearTimeout(mb.data('delay')); 
    mb.data('delay', setTimeout(function() { mb.fadeOut(1000); }, 5000)); 
} 

You can see a working demo here

+2

безупречный ответ! Большое спасибо! –

0

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

elem.stop().show().delay(5000).fadeOut(1000); 
+0

это не работает. попробовал это раньше. новое сообщение отображается, но в течение периода, оставшегося от этого 5 секунд первого сообщения. –

0

я получал конфликты CSS, потому что вы никогда не удалите классы MSG перед добавлением другой, поэтому я очистил тех, с elem.removeClass('msg_confirm msg_error'); в дополнение к устранению проблемы:

function display_message(msgType, message) { 

    var elem = $('#ur_messagebox'); 
    elem.removeClass('msg_confirm msg_error'); 

    switch (msgType) { 
     case 'confirm': 
      elem.addClass('msg_confirm'); 
      break; 

     case 'error': 
      elem.addClass('msg_error'); 
      break; 
    } 

    elem.stop().css({opacity:1}).clearQueue(); 
    elem.html(message); 
    elem.show().delay(5000).fadeOut(1000); 
} 

Так с elem.stop().css({opacity:1}).clearQueue(); я останавливаю анимацию, сбросьте непрозрачность в случае, если она была в середине затухания и очистите очередь перед добавлением сообщения и перезапуском очереди. Я тестировал это, и он должен работать для вас.

+0

nope! это тоже не работает. тем больше я вникаю в это, тем больше у меня появляется больше людей, имеющих проблемы с функцией задержки. читайте комментарии здесь http://api.jquery.com/delay/ –

+0

А, интересно, я только проверял некоторые случаи, но это не работает для всех. Будет продолжаться. – mVChr

0

Я перезапуске анимации следующим образом: (не уверен, что все верно, но)

$ (элемент) .stop(). clearQueue();

$ (элемент) .delay (20) .animate ({...});

1

Как Nick отметил:

Короче говоря, вы не можете использовать .delay() для того, что вы хотите.

Но есть обходное решение: вместо использования .delay(x) просто используйте .fadeTo(x,1).

В принципе, это будет исчезать до полной непрозрачности, но поскольку окно сообщения уже находится на полной непрозрачности, это ничего не делает, кроме как отсрочить следующие анимации для x миллисекунд. Преимущество состоит в том, что .fadeTo() можно остановить/прервать, используя .stop(true).

0

при использовании JQuery, просто закончить текущую анимацию перед тем, как снова:

tooltip.finish();// set a defined start for animation 
tooltip.show(); 
tooltip.delay(4000).fadeOut(1500); 
Смежные вопросы