3

I use mCustomScrollbar for an element on a page, which gets reloaded at times. It's a messages view, and when the user clicks on another conversation, the messages of this conversation get loaded. However, when I want to scroll to bottom after loading this, as the newest messages are at bottom, it scrolls not to bottom but a few pixels above bottom ("a few" can be randomly between 10 and 200px).

Below is a simplified example:

// code to load another conversation
$(".conversations .conversation").click(function (e) {
    var $this = $(this);
    $.ajax({
        url: W.sprintf('/messages/%s/fetch', $this.attr("data-cid")),
        dataType: 'html'
    }).done(function(data) {
        $('.main_pane.messages').html(data);
        // a function call to set the hight of .main_list.messages goes here
        $(".main_list.messages").mCustomScrollbar(W.scroll_prefs);
        $(".main_list.messages").mCustomScrollbar("scrollTo", "bottom");
        // also tried adding an element at bottom and scrolling to this
        // and scrollTo Number.MAX_VALUE
        // also tried putting the two mCustomScrollbar lines both into
        // setTimeout()
    });
});
<!-- this is what gets loaded -->
#conversation
  .head
    -# some foo
  .conv_body
    .main_list.messages.custom-scroll.hide-scrollbar.start-bottom
      -# basically a bunch of these below
      .listelem.msg
        .left
          = image_tag(user.avatar.image(:icon), size: avatar_size(:icon))
        .right
          %span.datetime= fmt_time(msg[:datetime], :time)
        .middle
          .name= link_to(user.login, user)
          .text= msg[:text]
    #new_message_container.main_input.open.threeline
      = form_for(@message) do |f|
        -# ...

CSS: just a few margins and paddings and colors and stuff, nothing fancy

SnoringFrog
  • 1,479
  • 1
  • 16
  • 30
linopolus
  • 93
  • 1
  • 1
  • 7

4 Answers4

9

I had the same problem , solved it by first calling the update and then adding a timeout of 1000 before I call the scrollTo bottom

$('#commentArea .mCSB_container ').append('<span class="oneComment">'+outputText+'</span><span class="commentBreaker"></span>');
$("#commentArea").mCustomScrollbar("update");
    setTimeout(function(){
        $("#commentArea").mCustomScrollbar("scrollTo","bottom");
    },1000);
Lau
  • 282
  • 3
  • 11
  • by putting this solution, scroll comes from top to bottom. I want to directly display the scroll at the bottom. How can I do this. Please help. – Nishant Aug 07 '18 at 09:19
  • thanks. it's work. but do not need to setTimeout function. only $("#commentArea").mCustomScrollbar("scrollTo","bottom"); is enough. – Ali Rasouli May 31 '20 at 20:27
4

It seems that you initialize the plugin each time new content is loaded via ajax. You should initialize the plugin once (outside of the click event):

$(".main_list.messages").mCustomScrollbar(W.scroll_prefs);

When ajax call completes and the new content is fully loaded, call mCustomScrollbar update method (updates the scrollbar according to the new content) and then scroll-to bottom:

$(".main_list.messages").mCustomScrollbar("update");
$(".main_list.messages").mCustomScrollbar("scrollTo", "bottom");
malihu
  • 790
  • 5
  • 6
  • I have to do this, as I destroy and recreate the element the scrollbar is on. If I just replace the initialization with update like you suggest, I get an error, because the element the scrollbar knows about/is on doesn't exist anymore: Uncaught TypeError: Cannot read property 'offsetTop' of undefined jquery.mCustomScrollbar.concat.min.js?body=1:5 Please correct me if I'm wrong – linopolus May 25 '13 at 14:20
  • 1
    I don't know how your html code is (how .main_pane.messages and .main_list.messages stack) but maybe this might be helpful... Your original content (in .main_list.messages) resides inside .mCSB_container div, so maybe you could append the ajax data in .mCSB_container (instead of directly .main_pane.messages). I don't know if this is doable as I don't know your html code. Also, you can try replacing 'done' with 'always' or 'complete', as it seems that content is not fully loaded when invoking scroll-to-bottom (loading images?). You could also add a time interval of say 1 sec to the scrollTo. – malihu May 28 '13 at 20:00
0

I used:

var d = $('#selector');
d.mCustomScrollbar({
    setTop: d.height() + "px"
});

to start at the bottom of a DIV.

vlemos
  • 1
0

Try adding padding to the bottom of the container you invoke the custom scrollbar on.

.main_list.messages  
{ 
  padding-bottom: 10px;   
}
mikeopoku
  • 11
  • 2