Search code examples
jqueryprototypejsslimscroll

Slimscroll scroll down only on div update


I am developing a chat with comet and i would like Slimscroll to scroll down only on div update because my chat script update a div by adding new messages to the div. So far i was able to make Slimscroll scroll down every 2 seconds.

PROBLEM But the problem is that it scrolls down whether the div has changed or not and because of that, the user can not scroll to top. How to make it scroll down only when the div with id messages_content has change or increase in size ?

This is my slimscroll code

  $(".slimscroll").slimscroll({
        height: "300px",
        color : "#0073b7",
        alwaysVisible: true,
        size: "10px",
        start: 'bottom',
        railVisible: true,
      railColor: '#0073b7',
      railBorderRadius: 0

    }).css("width", "100%");


     // update content every second
  setInterval(function(){

    // update slimscroll every time content changes
   var en_bas = $('.slimscroll').slimscroll({ scrollBy: '400px' });



  }, 2000);

And this is my Comet Code that uses prototypejs to fetch informations from the database.

<script type="text/javascript">

var Comet = Class.create();
Comet.prototype = {

  timestamp: 0,
  url: './messages_private_travail.php?id_du_membre_envoye=<?php echo $id_ojm_peoples; ?>&id_de_l_autre_originale=<?php echo $id_de_l_autre_originale; ?>&id_message=<?php echo addslashes(@$_GET['id_message']); ?>&chat_between=<?php $chat_between = hash('sha512',"Chat Between $id_ojm_peoples AND $id_de_l_autre_originale");  echo $chat_between;  ?>',
  noerror: true,

  initialize: function() { },

  connect: function()
  {
    this.ajax = new Ajax.Request(this.url, {
      method: 'get',
      parameters: { 'timestamp' : this.timestamp },
      onSuccess: function(transport) {
        // handle the server response
        var response = transport.responseText.evalJSON();
        this.comet.timestamp = response['timestamp'];
        this.comet.handleResponse(response);
        this.comet.noerror = true;
      },
      onComplete: function(transport) {
        // send a new ajax request when this request is finished
        if (!this.comet.noerror)
          // if a connection problem occurs, try to reconnect each 5 seconds
          setTimeout(function(){ comet.connect() }, 5000); 
        else
          this.comet.connect();
        this.comet.noerror = false;
      }
    });
    this.ajax.comet = this;
  },

  disconnect: function()
  {
  },


  handleResponse: function(response)

  {
      //$('messages_content').innerHTML += '<div>' + response['msg'] + '</div>';

    $('messages_content').innerHTML += ' ' + response['msg'] + ' ';



    //On appel la fonction qui permet de jouer le son 
    jouer_son('soundmanager2/audio/beep.mp3');  

    //On applique la fonction qui montre que le message a ete lu par le membre
    mettreajour('nombre_nouveaux_messages', 'messages_lire_marquer_comme_lu.php?id_du_membre_envoye=<?php echo $id_ojm_peoples; ?>&id_de_l_autre_originale=<?php echo $id_de_l_autre_originale; ?>&id_message=<?php echo addslashes(@$_GET['id_message']); ?>&chat_between=<?php $chat_between = hash('sha512',"Chat Between $id_ojm_peoples AND $id_de_l_autre_originale");  echo $chat_between;  ?>', '&id_ojm_peoples=<?php echo $id_ojm_peoples; ?>');


  },

  doRequest: function(request)
  {
    new Ajax.Request(this.url, {
      method: 'get',
      parameters: { 'msg' : request, evalScripts: true } 


    });
  }
}
var comet = new Comet();
comet.connect();
</script>

Solution

  • Rather than having to watch for the change event on the DOM, consider calling your scrolling function from the chat script function that adds the content to the div, if possible. For example:

    handleResponse: function(response) {
      jQuery('#messages_content').append(' ' + response.msg + ' ');
      jQuery('.slimscroll').slimscroll({ scrollBy: '400px' });
    }
    

    If the objective is to keep it from pushing the user back to the bottom when trying to scroll up, consider also having it only scroll when the user is already at the bottom. That way they can scroll up without being yanked down when a new post comes in, but when they are already at the bottom, it will stay at the bottom:

    handleResponse: function(response) {
      var messages_content = jQuery('#messages_content');
      var shouldScroll = messages_content[0].clientHeight + messages_content[0].scrollTop === messages_content[0].scrollHeight;
      messages_content.append(' ' + response.msg + ' ');
      if (shouldScroll) {
        jQuery('.slimscroll').slimscroll({ scrollBy: '400px' });
      }
    }