14

Twitter will pop down a message bar at the top of the screen say "Wrong password" and after 10 seconds, it will slide up and disappear. Chrome also shows "Do you want to save the password" message box using such a way.

Does jQuery have a plug in to do that already? Does it also work in IE 6? Because usually, the display of relative to the viewport (using position: fixed) will not work on IE 6. thanks.

Update: thanks for the nice solutions -- I deliberately wanted it to work (1) even when the user has scrolled down the page, that it will show at the top of the window screen and (2) the bar might be chosen to display at the bottom of window screen instead (as an option)... and if it works on IE 6 then it is even better... poor programmers nowadays...

nonopolarity
  • 130,775
  • 117
  • 415
  • 675
  • 2
    IE6 is like a decade old – Matti Virkkunen Jun 06 '10 at 10:41
  • Is something like this what you mean: http://www.tympanus.net/jbar/ Or do you mean with exactly the styling twitter has? – Nick Craver Jun 06 '10 at 10:45
  • 2
    That must be like 15 lines of code, maybe it's not worth a plugin ;-) – Tom Bartel Jun 06 '10 at 10:49
  • @Tom - I agree... *unless* you need IE6 support, in which case it's longer, but still I wouldn't use one either...I have the same effect for errors on a current project, it's not even 3 lines of code. – Nick Craver Jun 06 '10 at 10:54
  • @Nick yes, similar to that. Also, would be nice if it can slide down, and also if it has an option to push down the page content when the bar slides down. – nonopolarity Jun 06 '10 at 10:59
  • @Nick @Tom also, if it can be stackable, like the Stackoverflow site does, then it may also be a little bit more complicated. – nonopolarity Jun 06 '10 at 11:00

2 Answers2

26

You can do this with just a few lines of code, like this:

​​​​function topBar(​​​message) {
  $("<div />", { 'class': 'topbar', text: message }).hide().prependTo("body")
      .slideDown('fast').delay(10000).slideUp(function() { $(this).remove(); });
}

Then just give the class you use some styling, for example:

.topbar { 
    background: #990000; 
    border-bottom: solid 2px #EEE; 
    padding: 3px 0; 
    text-align: center; 
    color: white;
}​

You can view a working demo here, tweak as needed :) This creates a <div> on the fly, adds it to the top of the body, so no funky positioning to worry about, this should be just fine in IE6. When it's finished it'll slideUp and remove the <div> it created to cleanup. You can add a click handler to remove it instantly, etc, whatever your needs are.

Nick Craver
  • 594,859
  • 130
  • 1,270
  • 1,139
  • ah, works quite well! with 1 catch... if it is in other pages, where the page is longer than 1 screen height and the user has scrolled down, then the bar pops down, but the user won't be able to see it. – nonopolarity Jun 06 '10 at 11:27
  • @Jian - You'll have to decide which you want in that case...it'd be better to have it fixed or slide the page down, not both, though it is possible, did you not want it to push the page? And how much does IE6 matter? (It'll have this same problem both ways with extra code to support it) – Nick Craver Jun 06 '10 at 11:34
  • @Jian - Here's one option, simply scroll them to the top to see the error: http://jsfiddle.net/qezPE/3/ – Nick Craver Jun 06 '10 at 11:50
  • This doesn't seem to work in IE. To get it working I had to remove the "class" and then use the jQuery addClass function instead. I think IE treats the class as a reserved word. – John Jun 07 '10 at 13:08
  • @John - Try wrapping `class` in quotes, e.g. `"class": 'topbar'`, does that resolve it? – Nick Craver Jun 07 '10 at 13:13
  • @John - np :) I updated the answer the same way so it's cross-browser consistent. – Nick Craver Jun 08 '10 at 00:33
  • Thanks, works great, i used bootstrap and added class `navbar-fixed-top` like `class: 'topbar navbar-fixed-top'` this does the **trick to show the message when user has scrolled to bottom** . – Shaiju T Jun 23 '16 at 13:14
3

Well I played around and came up with this nice function:

[ live example on http://jsfiddle.net/2arVf/ ]

//
// Usage: sendMessage(message, yes_text, no_text, class_to_style, callback_yes, callback_no)  -- for yes/no
//    or: sendMessage(message, class_to_style[, timeout])  -- informative with optional auto-hide after timeout
//

var sendMessage = function(str,yes,no,my_class,callback_yes,callback_no) {

    clearMessageTimeout(); // clear the timeout so it doesn't accidentaly slide up

    if (typeof no == 'string') {   // check if this is a yes/no message

        $message.slideUp(0, function() {  // slide up if not already
            // scroll to the top so the user gets to see the message             
            $("html").animate({'scrollTop': 0}, 'fast', function() {    // then
                $message
                .unbind('mouseout').attr('class','')      // kill old classes
                .addClass(my_class)    // add our class styling
                .html([ str, '<br />', // create an array to add our
                                       // two handlers with #yes and #no IDs
                        '<button id="yes">', yes ,'</button>',
                        '<button id="no">' , no  ,'</button>'
                      ].join('')       // join the array and
                     )                 // insert message
                .slideDown(1000)       // slide the message down
                .find('#yes,#no')      // find #yes and #no
                .click(function() {    // add click handler to #yes and #no                            
                    var answer=$(this).attr('id');           // should be 'yes' or 'no'
                    $message.slideUp(1000, function() {      // slide up and
                        $("html").animate({'scrollTop': 0},  // scroll to top again and
                            eval('callback_' + answer)       // call our callback
                        );
                    });
                });     
            });        
        });

    } else {                  

        $message
            .unbind('mouseout')                // unbind previous mouseout
            .attr('class','')                  // kill old classes
            .addClass(yes)                     // add our class
            .html(str)                         // insert our message
            .slideDown(1000, function() {      // slide down the message
            $message.mouseout(function() {     // bind mouse out
                setMessageTimeout(function() { // with a timeout if the pointer comes back
                    $message.slideUp(1000);    // to slide back up
                }, 1000);                      // after 1 second
            });                           
        });

        if (typeof no == 'number') {       // if a timeout is specified
            setMessageTimeout(function() { // then it sets it
                $message.slideUp(1000);    // to slide up by itself
            }, no);                        // after x milliseconds
        }
    }
}

// Initialize messenger

$("<div></div>").prependTo('body').attr('id','message');

var $message = $("#message")
    .mousemove(clearMessageTimeout),
    message_timeout;

function setMessageTimeout(callback, time) {
    clearTimeout(message_timeout);
    message_timeout = setTimeout(callback, time);
}

function clearMessageTimeout() {
    clearTimeout(message_timeout);
}

Example:

$(".invoke_message").click(function(e) {

    sendMessage(

        [ 'Here I am, a message..',
          'I can be multiline',
          '<strong>and have any html</strong>',,
          'Do you like me?'
        ].join('<br />'),

        'Yeap','Nope',  // yes and no text

        'normal',       // normal class

        function() {    // yes callback
            sendMessage('Thank you. I\'ll be gone in 3 secs', 'happy', 3000);
        },

        function() {    // no callback
            sendMessage('OK, have it your way then. You need to mouseout me to make me leave', 'sad');
        }

    );

    return false;
});

CSS:

body {
    padding:0;
    margin:0;
}
strong {
    font-weight:bold;
}
#message {
    color:#fff;
    text-align:center;
}
.normal {
    background-color:#888;
}
.happy {
    background-color:#cc2;
}
.sad {
    background-color:#b44;
}

HTML:

<p>I'm the main page. I'll do some space if there is a message</p>
<p><a class="invoke_message" href="#">Click me</a></p>
.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br />.<br /><p><a class="invoke_message" href="#">Click me too</a></p>
stagas
  • 3,872
  • 3
  • 25
  • 28