In short, you cannot use .delay() for what you want. This is just a wrapper for setTimeout() in the next element of the queue, you can see the source here , an important role:
return this.queue( type, function() { var elem = this; setTimeout(function() { jQuery.dequeue( elem, type ); }, time ); });
So this is just the sequence of setTimeout() , which, when executed, discards the next element in the queue and executes it. So what happens, you added a delay, and even with .stop(true) or .clearQueue() , when you queue .fadeOut() after that, you add it back to the same fx , so when this setTimeout() ends after 5 seconds, he captures a new one that drops into the queue and executes it.
You need setTimout() and clear it manually, since the jQuery core does not have this built-in, something like this:
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)); }
Here you can see a working demo.
source share