how to stick an element on page (position: fixed) after it has been displayed?

283 views Asked by At

I'm developing a growl like notifications for my site, currently it's like this:

HTML:

<div id="growls"></div>

CSS:

#growls {
position: fixed;
right: 20px;
bottom: 20px;
}

.growl {
display: none;
}

JS:

function growl(message) {
    if (growls < 5) {
        growls = growls + 1;
        $('<div class="growl short block">' + message + '</div>').prependTo('#growls').fadeIn('slow').delay(2000).fadeOut('slow', function() { growls = growls - 1 });
        }
    }

Live example

It basically put new 'growl' on top of existing ones, problem is, when old ones disappear, new 'growls' suddenly collapse down, very annoying if you are reading the message.

I'm thinking about making the new growl div position fixed after it display, but it's not very clean (tons of adding and subtracting from elements offset)

Is there any better way to do this?

2

There are 2 answers

1
James Montagne On BEST ANSWER

I know it doesn't answer the exact question asked, but my suggestion would be to use slideUp to hide the elements instead of fadeOut. This will give a nice fluid movement for the other elements to move into their new position. This can easily be followed by the readers eye and won't cause the elements to jump.

Or for an even nicer look, use animate and animate the height and the opacity:

http://jsbin.com/exonal/4

$('<div class="growl short block">' + message + '</div>').prependTo('#growls')
    .fadeIn('slow').delay(2000)
    .animate({opacity: 0, height:"hide"},'slow', function() { growls = growls - 1 });
0
DefyGravity On
    $(document).ready(function(){
    // what is your jQuery version? this only works in 1.7+ otherwise use .delegate()
// register a hide show command for every .growl from page load and into the future.
       $("#growl").on("growlHideShow",".growl",{delayTime:2000}, function(event){
//slideToggle and fadeToggle are great.  change your display effect here with whatever you decide.
         $(this).slideToggle('slow');
         if($(this).is(":visible")){
//hide it after the 'delaytime' has passed.
           $(this).delay(event.data.delayTime).triggerHandler("growlHideShow");
         }
       });
    });

    function growl(message) {
    var growlDiv = $("#growl");
    var growlsList = $(".growls", growlDiv );
    var html = '<div class="growl short block">'+message+'</div>';
    if(growlsList.length >= 5){
    //you seemed to want to keep the growl count to 5. this removes the last one.
      $(growlsList[growlsList.length -1]).remove();
    }
      growlDiv.prepend(html);
      $(":first", growlDiv).triggerHandler("growlHideShow");
    }