tags:

views:

33

answers:

2

My question is pretty much as the title suggests, I have a message board which constantly expands and pushes messages down when new ones are added. I want to be able to lock the scroll to a message for example so the page scroll bar moves when the message board extends to keep the same view of messages that you had initially. Is this possible with jquery? Any advice appreciated.

+1  A: 

In my answer, you just need to send and attribute telling the order of messages. In example below, will scroll to "Message Bar", then to "new message".

You can use this.

HTML

Messages:

<div id="board">
    <span class="message" order="2">Message Foo</span>
    <span class="message" order="3">Message Bar</span>
    <span class="message" order="1">Message Test</span>
</div>

JS

$(document).ready(function(){   
    // each half second, updates scroll
    window.setInterval(updateScroll, 100);    

    // after 2 seconds, add new message to test scroll
    window.setInterval(newMessage, 2000);             
});

// find message with bigger order number, and scroll to it
function updateScroll(){
    var messages = $(".message");
    var newMessage = $(messages[0]);
    $(".message").each(function(){
        if ($(this).attr("order") > $(newMessage).attr("order")) {
            newMessage = $(this);
        }
    });
    var top = newMessage.offset().top;
    $(document).scrollTop(top);    
}

function newMessage() {
    var text = Date() + "<br/> - new message!";
    var tag = "<span order=\"9\" class=\"message\">" + text + "</span>";
    $('#board').prepend(tag);
}

See in jsfiddle


EDIT

Explanations:

  • $(document).ready: after page loads
  • window.setInterval(updateScroll, 100);: calls updateScroll function each 0.1 seconds.
  • $(".message").each(function(){...}): get the position of element with bigger order
  • $(document).scrollTop(top): scrolls page to that position
Topera
First of all, thank you for your response, really appreciate it. Your example however, just stays at the bottom, I was thinking more in terms of clicking on a target and then having the scroll bars focus on that target as more message come, so not necessarily bottom message, maybe middle message.
Scarface
@scarface: ok! I've edited my answer to your needs. Check it out. :)
Topera
+1  A: 

You'll need to register a callback or event handler that gets triggered whenever the content on the page changes.

The you'll need a scroll-to function. Check out http://demos.flesler.com/jquery/scrollTo/.

...
// Insert this code where you are adding the message to the page
// New message, trigger the custom event callback
// Assumes 'message' is a jQuery object for the new message.
message.trigger('scroll-to-message');
...

jQuery(function() {
  // Bind a handler for all messages (which should have a class 'message')
  // with a custom event name
  jQuery(document).delegate('.message', 'scroll-to-message', function() {
    var message = jQuery(this);
    jQuery.scrollTo(message);
  });
});
fullware
this looks like what I need, I didn't really want to add more extension code but this thing is kinda cool. I will try it, and let you know
Scarface
ok lol, I am starting to get extremely frustrated getting this thing to work. I have tried to implement it but I am getting no response. I have included jquery of course, the plugin script, of course, (I have alerted a test message to make sure it is there) and have tried different tests trying to make it work. I tried this <a href="#" onclick="$.scrollTo( '#footer', 800, {easing:'elasout'} );">label</a>
Scarface
I tried this jQuery(function() {$.scrollTo( '#footer', 800, {easing:'elasout'} );});
Scarface
I am not really sure what the issue is, maybe you have some insight...
Scarface
ok wow I figured it out, really stupid plugin because it gives an explanation that could have been mistaken for being written by someone mildly retarded. THE EASING code is not even part of the plugin, you have to implement seperately. Anyway I'll try to get this thing functioning like I want it and get back to you.
Scarface
I got it working how I need, thanks again for the suggestion
Scarface