Reputation: 44293
I have probably a simple problem to solve but I don't know what's the right approach on that.
I have a div.notification
bar on top of my website that is hidden by default. The bar does get an additional class of either success
or warning
that sets it to display:block;
if needed.
So, there are two cases. Either an output message is rendered directly to the .notification
bar on page-load (and it gets a class of success
or warning
right with it) OR the .notifcation
bar is sliding down from top and is fed with json data.
Any way, the notification bar should always be visible for 10 seconds and than slide back up.
Therefore I wrote two functions that handle this bar.
var timing = 10000;
function notificationOutput(type, message) {
var note = $('.notification');
note.hide();
note.find('.message').html(message);
note.stop(true,true).slideDown().delay(timing).slideUp();
}
function notificationSlideUp(slideUp) {
var note = $('.notification');
if ( slideUp ) note.delay(timing).slideUp();
else note.stop(true,true).slideUp();
}
So the notificationOutput()
function is triggered from various other functions that return json data and render that into the box.
And the notificationSlideUp()
function is right now called on every page load because in my header I have this …
<script type="text/javascript">
$(document).ready(function(){
notificationSlideUp(true);
});
</script>
And there is a reason for that! Remember the case where the .notification
is directly set to visible on page-load … e.g. when a user logs-in on my platform the .notification
bar is immediately visibile and says "Welcome Username, you've successfully logged in".
I call the notifictaionSlideUp()
function in my header to make sure the currently visible .notification
bar will slideUp() again after 10 seconds.
And here occurs the problem …
Somehow this causes the entire notifcation timing and sliding up and down to be "confused". So there must happen some queuing of the slide-functions and or of the delay() function, because without the note.stop(true,true)
in the notificationOutput()
function the notification wouldn't slideDown() immediately if it's triggered within the first 10 seconds after the page load. That is because the notificationSlideUp()
function has already triggered the slideUp() and the delay() of the object.
And the same happens to the delay. If a .notification
is put out within the first 10 seconds the delay timing isn't right because the delay counter already started on page-load.
Any idea how to solve that so that it always works?
Update:
var notificationTimer;
function notificationOutput(type, message) {
var note = $('.notification');
note.hide();
note.find('.message').html(message);
note.stop(true,true).slideDown();
clearTimeout(notificationTimer);
notificationTimer = setTimeout(function() {
note.stop(true,true).slideUp();
}, 10000);
}
function notificationSlideUp(slideUp) {
var note = $('.notification');
if ( slideUp ) {
clearTimeout(notificationTimer);
notificationTimer = setTimeout(function() {
note.stop(true,true).slideUp();
}, 10000);
} else {
note.stop(true,true).slideUp();
}
}
Upvotes: 1
Views: 322
Reputation: 16214
The .delay() method is best for delaying between queued jQuery effects. Because it is limited—it doesn't, for example, offer a way to cancel the delay—.delay() is not a replacement for JavaScript's native setTimeout function, which may be more appropriate for certain use cases.
But you can use the following 'hint' - replace delay with some animation which does not change anything. For example with .animate({opacity:1},timing)
Upvotes: 1
Reputation: 5227
Unfortunately, jQuery's delay()
function doesn't offer any method for canceling a delay the way setTimeout()
does with clearTimeout()
. I'd suggest replacing your delay()
s with named setTimeout()
s, and writing a condition to clearTimeout()
for cases in which you need to cancel/trigger a queued animation right away.
Upvotes: 1