AngularJS: Scroll to end of element after applying DOM changes

前端 未结 6 932
攒了一身酷
攒了一身酷 2020-12-29 20:16

I have a simple list of items. I want to be able to scroll to the bottom of the element displaying the items whenever I add more items. I understood there is no way of hooki

相关标签:
6条回答
  • 2020-12-29 20:51

    A simple working example (no need for plugins or directives)...

    .controller('Controller', function($scope, $anchorScroll, $location, $timeout) {
    
      $scope.func = function(data) {
    
        // some data appending here...
    
        $timeout(function() {
          $location.hash('end');
          $anchorScroll();
        })
      }
    
    })
    

    The trick that did it for me was wrapping the anchorScroll command with $timeout, that way the scope was resolved and it automatically shifted to an element at the end of the page.

    0 讨论(0)
  • 2020-12-29 20:57

    You could create a simple directive that bind a click handler that scrolls the <ul> to the bottom each time.

    myApp.directive("scrollBottom", function(){
        return {
            link: function(scope, element, attr){
                var $id= $("#" + attr.scrollBottom);
                $(element).on("click", function(){
                    $id.scrollTop($id[0].scrollHeight);
                });
            }
        }
    });
    

    example on jsfiddle

    0 讨论(0)
  • 2020-12-29 21:02

    Another valid solution to this is using $timeout. Using a timeout value of 0, angular will wait until the DOM is rendered before calling the function you pass to $timeout. So, after you add an element to the list, you can use this to wait for your new element to be added to the DOM before scrolling to the bottom.

    Like @Mark Coleman's solution, this won't require any extra external libraries.

    var myApp = angular.module('myApp', []);
    
    function MyCtrl($scope, $timeout) {
      $scope.list = ["item 1", "item 2", "item 3", "item 4", "item 5"];
      $scope.add = function() {
        $scope.list.push("new item");
        $timeout(function() {
          var scroller = document.getElementById("autoscroll");
          scroller.scrollTop = scroller.scrollHeight;
        }, 0, false);
      }
    }
    ul {
      height: 150px;
      overflow: scroll;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
    <div ng-app="myApp">
      <div ng-controller="MyCtrl">
        <button ng-click="add()">Add</button>
        <ul id="autoscroll">
          <li ng-repeat="item in list">{{item}}</li>
        </ul>
      </div>
    </div>

    0 讨论(0)
  • 2020-12-29 21:08

    You can use the AnchorScroll.. here the documentation: https://docs.angularjs.org/api/ng/service/$anchorScroll

    0 讨论(0)
  • 2020-12-29 21:08

    You can achieve this using angularjs custom directory.

    example :

    <ul style="overflow: auto; max-height: 160px;" id="promptAnswerBlock">
    
    <li ng-repeat="obj in objectKist track by $index" on-finish-render="ngRepeatFinished">                                              
    
      app.directive('onFinishRender', function($timeout) {
        return {
            restrict : 'A',
            link : function(scope, element, attr) {
                if (scope.$last === true) {
                    $timeout(function() {
                        $('#promptAnswerBlock').scrollTop($('#promptAnswerBlock')[0].scrollHeight + 150);
                    });
                }
              }
            }
        }); 
    
    </li>
    
    0 讨论(0)
  • 2020-12-29 21:14

    There's the very awesome angularjs-scroll-glue available, which does exactly what you want.

    All you need to do is to apply the scroll-glue directive to your container element, and you get exactly what you're looking for.

    There's also a demo available.

    0 讨论(0)
提交回复
热议问题