2

Ok, here's my situation:

I've been working on a chatroom type website for a side-project/hobby. The current layout uses html frames. The bottom frame is the "footer", or "message input" frame. The top frame is where the public messages are displayed. I use ajax to update the top frame every second. It works fine. My issue is this:

I need to be able to keep the top frame scrolled all the way to the bottom -- UNLESS the user scrolls back up to view old messages, for example. I currently have a function that keeps it scrolled down to the bottom, but every time ajax updates the page, it forces it back down to the bottom, so I can't scroll back up for more than about a second, and it's really frustrating. I have searched for a solution, but i've not found any that actually work for me. The function that I use to scroll to the bottom is as follows:

function jumpToPageBottom() {
    $('html, body').scrollTop( $(document).height());
}

It does it's job, but again, I need it to stop forcing the page to the bottom if a user scrolls back up to view older messages.

UPDATE --

I should clarify, I'm using actual frames, rather than an iframe. My "index" page code is:

<FRAMESET ROWS="*,90">
<FRAME SRC="header.php" name="display" MARGINWIDTH="0" MARGINHEIGHT="0" FRAMEBORDER="NO">
<FRAME SRC="footer.php" name="message" SCROLLING="no" BORDERCOLOR="00FF00" MARGINWIDTH="0" MARGINHEIGHT="0">
</FRAMESET>

And the code that refreshes my chat messages is:

<script id="source" language="javascript" type="text/javascript">
  function jumpToPageBottom() {
    $('html, body').scrollTop( $(document).height());
}


    $(function() {
    startRefresh();
});

function startRefresh() {
    setTimeout(startRefresh,1000);
  $.ajax({                                      
      url: 'api.php',                  //the script to call to get data          
      data: "",                        //you can insert url argumnets here to pass to api.php
                                       //for example "id=5&parent=6"
      dataType: 'json',                //data format      
      success: function(data)          //on recieve of reply
      {

        //--------------------------------------------------------------------
        // 3) Update html content
        //--------------------------------------------------------------------

        $('#output').html(data); //Set output element html   
           jumpToPageBottom();

      } 
    });
  }; 

  </script>

Is the refreshing like that just a bad approach? Is the way that the div is updated causing some of my issues? I'm new to all of this (obviously) -- so any advice would be much appreciated.

Mike Roberts
  • 161
  • 2
  • 14
  • 1
    Do a check to only scroll down only when the user is already scrolled at the bottom? On message receive: 1. Get if the user is scrolled to the bottom 2. Add the message. 3. Scroll to bottom if 1 was true. – David Sherret Apr 17 '15 at 01:59
  • I get the logic, I guess I just don't understand the syntax for that. I'm not too JS or jquery savvy just yet, but I'm trying to learn. I've been googling exactly what you said, but I've come up short so far. I'll keep checking though. Thanks! – Mike Roberts Apr 17 '15 at 02:07
  • I'll write up an answer. – David Sherret Apr 17 '15 at 02:08

1 Answers1

3

The basic logic you need is:

var wasAtBottom = isAtBottom();

$('#output').html(data);

if (wasAtBottom) {
    jumpToPageBottom();
}

With isAtBottom being from this answer:

function isAtBottom() {
    return $(window).scrollTop() + $(window).height() === $(document).height();
}

Here's a working demo for you: http://jsfiddle.net/9q17euuo/2/

Community
  • 1
  • 1
David Sherret
  • 101,669
  • 28
  • 188
  • 178
  • I've updated my question to include more code. I thought for sure your answer was going to work, because it does make sense - I just can't get it to fire right. I think it may have something to do with the way my div is updated. Could I be doing things all wrong? – Mike Roberts Apr 17 '15 at 02:41
  • Try to see what the value is of `$(window).scrollTop() + $(window).height()` and `$(document).height()` in the frame. – David Sherret Apr 17 '15 at 02:48
  • I used a function I found online to show me what the values were, and it looks like about 819px - does that help? Also, the div I use that gets updated is: `
    ` should that be different somehow? I'm really sorry for all of the silly questions.. I'm just a total noob when it comes to this
    – Mike Roberts Apr 17 '15 at 02:55
  • @MikeRoberts are they equal when the user is scrolled to the bottom? Maybe just check the jsfiddle link I posted and try to see how you can apply that to your scenario. – David Sherret Apr 17 '15 at 02:56
  • It seems to work great in IE! Thank you for that. Is there a reason why it won't work in chrome? I'm going to accept this answer though, because it definitely does the trick in IE, and I'm sure I'm just doing something minor that makes chrome act up – Mike Roberts Apr 17 '15 at 03:12
  • @MikeRoberts does the example not work for you in chrome? I'm using chrome :) -- I updated the fiddle to display the values that need to be equal for it to scroll. – David Sherret Apr 17 '15 at 03:18
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/75452/discussion-between-mike-roberts-and-david-sherret). – Mike Roberts Apr 17 '15 at 03:30