Scroll down page **completely** when template is rendered


#1

I have a chat-like application where different chat-rooms can be accessed (using flow-router FlowRouter.route('/chat/:room_id'...).

What I am trying to achieve is that when a chat is accessed the UI starts with the chat completely scrolled down to the last element. However, with all my approaches there are sometimes situations where the screen is not completely scrolled down, but somewhere in the middle or not scrolled at all. Most of the situations can be addressed via adding a timeout to the scrolling below, but I would prefer to do it without some “arbitrary” timeout, which again is not really reliable.

Is there a recommended technique with Meteor for what I am trying to achieve?

This is the pattern of my current approach:

<template name="chat>
     <div class="content-scrollable" id="scrollingList"> 
        <ul>
        {{#each messages}}
            <li>{{> Template.dynamic template=type}}</li>
        {{/each}}
        </ul>
    </div>
</template>

<template name="chatType1Element">
    <p> content type 1 </p>
</template>

<template name="chatType2Element">
    <p> content type 2 </p>
</template>
Template.chat.onRendered(function(){
     Meteor.defer(function(){
        console.info("scrolling...");
         //GSAP ScrollToPlugin, other approaches produced similar results
        TweenLite.to("#scrollingList", .1, {
            scrollTo: {
                y: "max" //scrolls completely down
            }, 
             onComplete: function() {
                console.log("scrolled down ..."); //hide loading screen here
             }                
        });     
    });
});

#2

Does it need to scroll down, or can it simply render to the bottom-most element? If the later is acceptable, use a blaze helper to detect the window size and/or last element, and write to the style attribute of your element.


#3

@awatson1978. Thanks for your answer. No there is no need for scrolling - your proposal sounds much better (rendering the list directly so that it appears at the bottom). Do you have an example how to do that?


#4

Anybody a hint on how to do that: rendering to the bottom-most element? Would really appreciate any example. Thanks.


#5

Ah, sorry. Was on the road yesterday, and didn’t respond.

Take a look at this file for another way to think about the issue and a bit of inspiration.

This file is dynamically resizing a transparent background div to match the size of a div containing text that has variable height based on window size. You could maybe detect the height of your div, then write a style that offsets location, or uses a $.scrollTo, or any number of other things.


#6

https://github.com/copleykj/socialize-messaging-demo/blob/master/views/partials/message/client/message.js#L22


#7

@copleykj. Thanks for the snippet! Can you be sure that if(this.data._id === messageId) refers to the message that is rendered last? I have messages with different content, some including photos while others only text…


#8

Yes, it’s a check to see if the message being rendered is the last message in the set… It will be true for the last message in the first set and each individual message that comes in after the conversation is loaded. If you have messages images then you may run into issues where the image is not fully loaded before onRendered completes… In which case you might want to try attaching a loaded event which scrolls for the image load as well.