1

I want scroll to the bottom of the div on page load but it's not doing it. I am able to scroll once the page loads.

CSS (hidden scroll bar)

.scrollable {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
.scrollable-hidden-parent {
    width: 100%;
    height: 100%;
    overflow: hidden;
}

.scrollable-hidden-child{
    width: 100%;
    height: 100%;
    overflow-y: scroll;
    padding-right: 17px; 
    box-sizing: content-box;
}

HTML - uses the init function to attempt to scroll to bottom on load

<div class="scrollable" ng-controller="MatchDetailController as matchdetail"
     ng-init="init()">
  <div class="scrollable-hidden-parent" >
     <div class="scrollable-hidden-child" id="scrollable-hidden">
        <div ng-repeat="message in chats>
             <b>{{message.name}}</b>&nbsp;&nbsp;{{message.message}}
         </div>
      </div>
   </div>   
</div>

Controller

app.controller('MatchDetailController', ['$scope', '$http', '$location', '$rootScope', '$window', function MatchDetailController($scope,$http,$location,$rootScope, $window) {

   $scope.init = function() {
       var objDiv = document.getElementById("scrollable-hidden");
       objDiv.scrollTop = objDiv.scrollHeight;
   };

}]);
georgeawg
  • 48,608
  • 13
  • 72
  • 95
KcYxA
  • 243
  • 1
  • 3
  • 19
  • There are only a few appropriate uses of `ngInit` directive and this is not one of them. For more information, see [AngularJS ng-init Directive API Reference](https://docs.angularjs.org/api/ng/directive/ngInit). – georgeawg Jun 30 '19 at 18:43
  • An element will not scroll if it is not the one overflowing. What are you doing in CSS to make that element overflow? – georgeawg Jun 30 '19 at 18:50
  • @georgeawg Thanks. I've edited the post to add mo details and CSS. Scrolling works, just doesn't scroll to bottom on load. – KcYxA Jun 30 '19 at 19:13
  • The most likely cause is the `ng-repeat` directive. The browser has not rendered the `
    ` elements added by that directive to the DOM before the function fetches `scrollHeight`. The code needs to wait for the `ng-repeat` directve to add the elements to the DOM and the browser to render the new DOM.
    – georgeawg Jun 30 '19 at 19:32
  • One option in this case is to make a directive to do the scrolling and then in the `link` function wrap the code that scrolls in a `$timeout`. This will ensure that the DOM has loaded prior to the code that scrolls being called. The directive should be inside the `ng-repeat` with `ng-if="$last"`. – Lex Jun 30 '19 at 22:32
  • @Lex Thank you! It works great. Posted the solution below. – KcYxA Jul 02 '19 at 01:29
  • @georgeawg Thanks for your help and setting me on the right path! Posted the solution below. – KcYxA Jul 02 '19 at 01:30

1 Answers1

2

With the help above, this is what I ended up doing:

Directive

//automatically scrolls to the bottom of the list on load
app.directive('scrollToBottom', function($timeout) {
    return {
        link: function(scope, element, attr) {
            if (scope.$last === true) {
                  $timeout(function() {
                      var scroll_id = attr.scrollId;
                      var objDiv = document.getElementById(scroll_id);
                      objDiv.scrollTop = objDiv.scrollHeight;
                  }, 0);
            }
        }
    };
});

HTML

<div class="scrollable-hidden-parent">
   <div class="scrollable-hidden-child" id="scrollable-hidden">
      <div ng-repeat="message in chats" scroll-to-bottom scroll-id="scrollable-hidden">
          <div>{{message.name}}&nbsp;&nbsp;{{message.message}}</div>
       </div>
    </div>
</div>

CSS

.scrollable-hidden-parent {
    width: 100%;
    height: 100%;
    overflow: hidden;
}

.scrollable-hidden-child{
    width: 100%;
    height: 100%;
    overflow-y: scroll;
    padding-right: 17px; 
    box-sizing: content-box;
}
KcYxA
  • 243
  • 1
  • 3
  • 19