在设定时间向下滚动聊天,但停用用户互动

I'm writing a web Chat system to permit user to write a message to their friend but I have a problem scrolling down the new messages using jquery.

I have these files:
messages.php where I store the form for submitting and view the messages;
chatupd.js executes post and get messages and refresh the div every 'x' seconds;
post_updmsg.php Prints messages to database;
get_updmsg.php Gets the latest messages from database;

But the only files needed for this question are the first two:

messages.php

<div class='chatContainer'>
    <div class='chatHeader'>
        <h3>Welcome <?php echo get_talkm3_nome(); ?></h3>
    </div>
    <div class='chatMessages'>
        <?php
include '../core/config.inc.php';
$db = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$id_usr_2 = $_SESSION['email'];
//Get Messages
$query = $db->prepare("SELECT * FROM `chat_t3`");



$query->execute();

            //Fetch
while ($fetch = $query->fetch(PDO::FETCH_ASSOC))
{
    $id_usr_2 = $fetch['id_usr_2'];
$id_usr_1 = $fetch['id_usr_1'];
    $text = $fetch['text'];
    $date = $fetch['date'];
    if ($id_usr_1 == $_SESSION['email']){   
    echo "<li class='message_container'><div class='sender'>From - <b>".ucwords($id_usr_1)."</b> TO - ".ucwords($id_usr_2)."</b> - ".$text." ".ucwords($date)."</div></li> ";
    } else {
    echo "<li class='message_container'><div class='reader'>From - <b>".ucwords($id_usr_1)."</b> TO - ".ucwords($id_usr_2)."</b> - ".$text." -".ucwords($date)."</div></li> ";
}
}
        ?>
    </div>
    <div class='chatBottom'>
        <form action='#' onSubmit='return false;' id='chatForm'>
        <input type='hidden' id="id_usr_1" value="<?php echo get_talkm3_email() ?>"><br />
        <input type='text' id='id_usr_2' value="" placeholder="inserisci la mail del destinatario" />
        <input type='text' name='text' id='text' value='' placeholder='Type your message'>
        <input type='submit' name='submit' value='Post'>
        </form>
        <br>

    </div>
</div>

chatupd.js

$(function(){
    $(document).on('submit', '#chatForm', function(){
        var id_usr_1 = $.trim($("#id_usr_1").val());
        var id_usr_2 = $.trim($("#id_usr_2").val());
        var text = $.trim($("#text").val());

        if (id_usr_1 != "" && id_usr_2 != "" && text != ""){
            $.post('../core/chat/post_updmsg.php', {id_usr_1: id_usr_1, id_usr_2: id_usr_2, text: text}, function(data){
                $(".chatMessages").append(data);
            });
        } else {
            alert("Data Missing");
        }
    });

    function getMessages (){
        $.get('../core/chat/get_updmsg.php', function(data){
            $(".chatMessages").html(data);
        });
    }

    setInterval(function(){
        getMessages();
    }, 1000);
});

Now, my questions are:

  • How can I automatically scroll down the page to display latest message? But if the user wants to see the old messages and scroll up the page, prevent that after 'x' seconds they is redirected to the bottom of the page?
  • If the user scrolls up the page and script to scroll down is blocked, how to reactivate it when user scroll down completely the page?

Among other implementations there are two (nice) ways to achieve what you want.
The first is the one you want:

Not at bottom (User scrolled up) > Lock scroll

jsBin demo

If the user scrolls the messages > don't scrollToBottom at new message arrival:

var $chat = $(".chatMessages");
var chatHeight = $chat.innerHeight();
var c = 1;
var chatIsAtBottom = true;


function newMessage() {
  $chat.append("<li>This is message "+ (c++) +"</li>");
  if(chatIsAtBottom){
    $chat.stop().animate({
      scrollTop: $chat[0].scrollHeight - chatHeight
    },600);
  }
}

function checkBottom(){
  chatIsAtBottom = $chat[0].scrollTop + chatHeight >= $chat[0].scrollHeight;
}

$chat.scrollTop( $chat[0].scrollHeight ).on("scroll", checkBottom);
setInterval( newMessage, 2000 );
  • Pros: Other events will not mess with the current user-defined scroll position.
  • Cons: In this example, while leaving the Messages scroll area you need to notify the user about "[New unread messages]" > that will on click scroll back to bottom.

Hover/Focus on Comment-area > Toggle-lock scroll

jsBin demo

The other one is related to this old post of mine that does:

If user hovers the messages area (Logically he's: 1. Scrolling, reading, copying some old text etc... interacting :) ) - than prevent scroll

var $chat = $(".chatMessages");
var chatHeight = $chat.innerHeight();
var c = 1;

function newMessage() {
  $chat.append("<li>This is message "+ (c++) +"</li>");
  if(!$chat[0].noScroll) {
    $chat.stop().animate({scrollTop: $chat[0].scrollHeight-chatHeight},600);
  }
}

$chat.hover(function() {
  return this.noScroll ^= 1;
});

$chat.scrollTop( $chat[0].scrollHeight );
setInterval( newMessage, 2000 );
  • Pros: Straightforward UI
  • Cons: It's cool and intuitive in most cases, but might be annoying if the user was i.e: copying a message from that scrolled board - on mouseleave the scroll-bottom might prevent the user from doing more actions on that exact scroll position.