简体   繁体   中英

Angularjs : Scroll to bottom of div

I'm having trouble scrolling to last message.

 var app=angular.module('myApp', ['ngMaterial'] ); app.controller('ChatCtrl', function($window, $anchorScroll){ var self = this; self.messageWindowHeight = parseInt($window.innerHeight - 170) + 'px'; self.messages = []; for(var i = 1 ; i<=200;i ++){ self.messages.push(i); } self.user = { text : ""}; self.send = function(){ self.messages.push(angular.copy(self.user.text)); self.user.text = ""; } }); app.directive('scrollToBottom', function($timeout, $window) { return { scope: { scrollToBottom: "=" }, restrict: 'A', link: function(scope, element, attr) { scope.$watchCollection('scrollToBottom', function(newVal) { if (newVal) { $timeout(function() { element[0].scrollTop = element[0].scrollHeight; }, 0); } }); } }; }); 
 /* Styles go here */ .chat-box { padding: 8px; border-radius: 8px; } .message-box { border-top: 1px solid #E0E0E0; position: fixed; right: 0; bottom: 0; width: 100%; height: 120px; background: white; } .message { overflow: scroll; margin: 4px; border: 1px solid #E0E0E0; -webkit-border-radius: 8px; -moz-border-radius: 8px; border-radius: 8px; height: 110px; } 
 <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.0.9/angular-material.css"> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:300,400,500,700,400italic"> </head> <body ng-app='myApp' layout="column" layout-fill ng-controller="ChatCtrl as ctrl"> <!-- content starts here --> <md-toolbar class="md-whiteframe-z2"> <div class="md-toolbar-tools"> <h2> hello </h2> </div> </md-toolbar> <md-content layout="column" style="background-color: #F5F5F5;" ng-style="{'height':ctrl.messageWindowHeight}"> <div class="chat-box"> <ol class="discussion" scroll-to-bottom="ctrl.messages"> <li ng-repeat="message in ctrl.messages track by $index" id="msg-{{$index}}"> {{message}} </li> </ol> </div> </md-content> <form name="userForm" novalidate ng-submit="ctrl.send()" layout="row" layout-padding layout-align="center center" class="message-box"> <div class="message" flex> <md-input-container class="md-block"> <input type="text" name="text" ng-model="ctrl.user.text" /> </md-input-container> </div> <md-button class="md-icon-button" type="submit"> send </md-button> </form> <!-- content ends here --> <!-- Angular Material Dependencies --> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-aria.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.0.9/angular-material.js"></script> <script src="script.js"></script> </body> </html> 

Here's a plunk of my code.

Move the scroll-to-bottom directive to the md-content element

 <!-- MOVE directive here -->
 <md-content ͟s͟c͟r͟o͟l͟l͟-͟t͟o͟-͟b͟o͟t͟t͟o͟m͟=͟"͟c͟t͟r͟l͟.͟m͟e͟s͟s͟a͟g͟e͟s͟"͟ layout="column"
             style="background-color: #F5F5F5;" 
             ng-style="{'height':ctrl.messageWindowHeight}">
      <div class="chat-box">
        <!-- NOT HERE -->
        <ol class="discussion" ̶s̶c̶r̶o̶l̶l̶-̶t̶o̶-̶b̶o̶t̶t̶o̶m̶=̶"̶c̶t̶r̶l̶.̶m̶e̶s̶s̶a̶g̶e̶s̶"̶ >
          <li ng-repeat="message in ctrl.messages track by $index" id="msg-{{$index}}">
            {{message}}
          </li>
        </ol>
      </div>
  </md-content>

The scroll-to-bottom directive needs to operate on the element that is actually scrolling. The element that is scrolling is the <md-content> element because its height is restricted by the CSS created by its ng-style directive. The <ol> element is not scrolling and its scrollHeight property is constant.

The DEMO

 var app=angular.module('myApp', ['ngMaterial'] ); app.controller('ChatCtrl', function($window, $anchorScroll){ var self = this; self.messageWindowHeight = parseInt($window.innerHeight - 170) + 'px'; self.messages = []; for(var i = 1 ; i<=200;i ++){ self.messages.push(i); } self.user = { text : ""}; self.send = function(){ self.messages.push(angular.copy(self.user.text)); self.user.text = ""; } }); app.directive('scrollToBottom', function($timeout, $window) { return { scope: { scrollToBottom: "=" }, restrict: 'A', link: function(scope, element, attr) { scope.$watchCollection('scrollToBottom', function(newVal) { if (newVal) { $timeout(function() { element[0].scrollTop = element[0].scrollHeight; }, 0); } }); } }; }); 
 /* Styles go here */ .chat-box { padding: 8px; border-radius: 8px; } .message-box { border-top: 1px solid #E0E0E0; position: fixed; right: 0; bottom: 0; width: 100%; height: 120px; background: white; } .message { overflow: scroll; margin: 4px; border: 1px solid #E0E0E0; -webkit-border-radius: 8px; -moz-border-radius: 8px; border-radius: 8px; height: 110px; } 
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.0.9/angular-material.css"> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:300,400,500,700,400italic"> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-aria.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.0.9/angular-material.js"></script> <body ng-app='myApp' layout="column" layout-fill ng-controller="ChatCtrl as ctrl"> <!-- content starts here --> <md-toolbar class="md-whiteframe-z2"> <div class="md-toolbar-tools"> <h2> hello </h2> </div> </md-toolbar> <md-content scroll-to-bottom="ctrl.messages" layout="column" style="background-color: #F5F5F5;" ng-style="{'height':ctrl.messageWindowHeight}"> <div class="chat-box"> <ol class="discussion"> <li ng-repeat="message in ctrl.messages track by $index" id="msg-{{$index}}"> {{message}} </li> </ol> </div> </md-content> <form name="userForm" novalidate ng-submit="ctrl.send()" layout="row" layout-padding layout-align="center center" class="message-box"> <div class="message" flex> <md-input-container class="md-block"> <input type="text" name="text" ng-model="ctrl.user.text" /> </md-input-container> </div> <md-button class="md-icon-button" type="submit"> send </md-button> </form> </body> 

Instead of setting scrollTop , use element[0].scrollIntoView(false); . See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM