2013-06-25 44 views
34

我有一個簡單的項目列表。我希望能夠在添加更多項目時滾動到顯示項目的元素的底部。我知道有沒有辦法掛鉤到$apply()函數的末尾,那麼我的解決方案可能是什麼?AngularJS:應用DOM更改後滾動到元素末尾

這是一個jsfiddle來說明我的問題。在添加足夠的項目之後,ul元素不會滾動到底部...

回答

69

有非常真棒angularjs-scroll-glue可用,這不正是你想要的東西。

您只需將scroll-glue指令應用於您的容器元素,即可獲得您要查找的內容。

還有一個demo可用。

+3

這是一個很好的解決方案,但我不想使用許多外部庫。你知道如何編碼嗎? –

+3

@JohnNguyen:那是[開源](https://github.com/Luegg/angularjs-scroll-glue/blob/master/src/scrollglue.js)。 –

+2

值得依賴..這種類型的DOM監視過程,然後進行滾動生成不必要的代碼..在這種情況下,這個庫完全適合.. –

5

您可以創建一個簡單指令,該指令綁定每次都將滾動條<ul>滾動到底部的點擊處理程序。

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

感謝馬克它幫助我。這可以稍微更好地用$超時服務更新。我更新了jsfiddle http://jsfiddle.net/w5Vgw/99/。 – Dilip

+0

雖然這是一個很好的小指令,但它並不能解決問題。它立即滾動而無需等待新元素添加到DOM。 – zendu

23

這個另一種有效的解決方案是使用$timeout。使用超時值0,角度將等待,直到DOM被渲染,然後調用傳遞給$timeout的函數。因此,在將元素添加到列表後,可以使用它等待在滾動到底部之前將新元素添加到DOM。

@Mark Colemansolution,這將不需要任何額外的外部庫。

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

或者您也可以在鏈接中觀看您的收藏集,然後滾動到該元素。您還可以輕鬆訪問鏈接中的元素... – Void

+0

此解決方案使控制器知道DOM,並直接操縱它。這不會被認爲是無棱角的嗎?或許更好地在指令中做那部分? – tom

5

一個簡單的工作示例(無需插件或指令)......

.controller('Controller', function($scope, $anchorScroll, $location, $timeout) { 

    $scope.func = function(data) { 

    // some data appending here... 

    $timeout(function() { 
     $location.hash('end'); 
     $anchorScroll(); 
    }) 
    } 

}) 

認爲這樣做是對我來說是用包裹在$timeout命令anchorScroll的訣竅,這樣,範圍就被解決了,並且它自動轉移到頁面末尾的一個元素上。

+0

感謝您提供優質簡單的解決方案。它的工作原理和幫助我) –

+0

簡單,但有一點需要注意的是,它修改了哈希值的網址。 –

-1

您可以使用angularjs自定義目錄來實現此目的。

例如:

<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

ng-repeat =「attribute.attributeValueList track中的attributevalue by $ index」on-finish-render =「ngRepeatFinished」 –

+0

請格式化您的代碼 – adao7000