0

I am making a web chat with JavaScript, PHP and MySQL my idea its to get information from database with chat.php and display it on <ol id ="chat_body" class="chat"></ol> with and <li class="other"></li>. The problem is when If I use $.ajax with a setInterval I cant scroll the scrollbar to the last message. I try this but doesnt work

var refreshMessages = function() {
$.ajax({
url: 'chat.php',
type: 'GET',
dataType: 'html'
})
//Check If Last Message Is In Focus
var checkFocus = function() {
var container = $('#chat_body');
var height = container.height();
var scrollHeight = container[0].scrollHeight;
var st = container.scrollTop();
var sum = scrollHeight - height - 32;
if(st >= sum) {
    return true;
} else {
    return false;
}
}
.done(function(data) {
if(checkFocus()) {
    $('#chat_body').html(data);
    scrollDownChat();
} else {
   $('#chat_body').html(data);
}
</script>

chat.php

<?php include "../connection.php";?>
<?php session_start();?>
<?php
$de_id = $_SESSION['ID'];
$chat = $_SESSION['para'];
$get_para_id = "SELECT id FROM users where username = '$chat'";
$get_para_id_con = $connect->query($get_para_id);
$get_para_id_result = $get_para_id_con->fetch_assoc();
$para_id = $get_para_id_result['id'];
$obtermensagens = "SELECT * FROM mensagens";
$obtermensagens_con = $connect ->query($obtermensagens);

while ($r = $obtermensagens_con->fetch_assoc()){
    if ($r['de_id'] == $de_id and $r['para_id'] == $para_id){
        echo "
            <li class='self'>
                <div class='avatar'><img src='https://i.imgur.com/DY6gND0.png' draggable='false'/></div>
                <div class='msg'>
                    <p>$r[conteudo]</p>
                <time>20:17</time>
                </div>
            </li>";
    }       
    elseif ($r['de_id'] == $para_id and $r['para_id'] == $de_id){
        echo "
            <li class='other'>
                <div class='avatar'><img src='https://i.imgur.com/DY6gND0.png' draggable='false'/></div>
                <div class='msg'>
                    <p>$r[conteudo]</p>
                    <time>20:17</time>
                </div>
            </li>";

    }
}   

?>

1 Answers1

0

I combined techniques from How to tell if a DOM element is visible in the current viewport? and How do I get an element to scroll into view, using jQuery?

to get what I think you were after. Essentially each time you append a message, you'll need to check if the message is visible, if not then you'll need to retrieve it's position and scroll to it. If you had these messages in a container with overflow then you would use it instead of html/body.

var messageNumber = 1;
(function(window, document, undefined)
{
  addMessage();
})(window, window.document);


function addMessage()
{
  var chatList = document.getElementById('chat');
  var newMessage = '<li>Message ' + messageNumber + '</li>';
  var lastMessage;
  var messageCount;
  var pos;
  
  chatList.insertAdjacentHTML('beforeend', newMessage);
  messageCount = chatList.children.length;
  lastMessage = chatList.children[messageCount - 1];
  
  if (!isElementInViewport(lastMessage)) {
    pos = $(lastMessage).offset();
    $('html, body').animate({
      scrollTop: pos.top,
      scrollLeft: pos.left
    });
  }
  
  messageNumber++;
  if (messageCount < 50) {
    setTimeout(addMessage, 300);
  }      
}

function isElementInViewport (el)
{

    //special bonus for those using jQuery
    if (typeof jQuery === "function" && el instanceof jQuery) {
        el = el[0];
    }

    var rect = el.getBoundingClientRect();

    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= $(window).height() &&
        rect.right <= $(window).width()
    );
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ol id="chat"></ol>
Russell
  • 476
  • 2
  • 10