AngularJS: прокрутите до конца элемента после применения изменений DOM
У меня есть простой список элементов. Я хочу иметь возможность прокручивать нижнюю часть элемента, отображающего элементы, когда я добавляю больше элементов. Я понял, что нет возможности подключиться к концу функции $apply()
, так что может быть моим решением?
Вот пример jsfiddle, чтобы проиллюстрировать мою проблему. после добавления достаточного количества элементов элемент ul не прокручивается до нижнего...
Ответы
Ответ 1
Там есть очень удивительный angularjs-scroll-glue, который делает именно то, что вы хотите.
Все, что вам нужно сделать, это применить директиву scroll-glue
к вашему элементу контейнера и получить именно то, что вы ищете.
Там также доступна демонстрация.
Ответ 2
Другим правильным решением для этого является использование $timeout
. Используя значение тайм-аута 0, angular будет ждать, пока DOM будет отображаться перед вызовом функции, которую вы передаете, на $timeout
. Таким образом, после добавления элемента в список вы можете использовать это, чтобы дождаться добавления нового элемента в DOM перед прокруткой вниз.
Как @Mark Coleman решение, это не потребует дополнительных внешних библиотек.
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>
Ответ 3
Вы можете создать простую директиву, которая привязывает обработчик кликов, который каждый раз прокручивает <ul>
до конца.
myApp.directive("scrollBottom", function(){
return {
link: function(scope, element, attr){
var $id= $("#" + attr.scrollBottom);
$(element).on("click", function(){
$id.scrollTop($id[0].scrollHeight);
});
}
}
});
пример на jsfiddle
Ответ 4
Простой рабочий пример (нет необходимости в плагинах или директивах)...
.controller('Controller', function($scope, $anchorScroll, $location, $timeout) {
$scope.func = function(data) {
// some data appending here...
$timeout(function() {
$location.hash('end');
$anchorScroll();
})
}
})
Трюк, который сделал это для меня, заключался в завершении команды anchorScroll с помощью $timeout
, таким образом область была разрешена и автоматически переместилась в элемент в конце страницы.
Ответ 5
Вы можете использовать AnchorScroll.. здесь документация: https://docs.angularjs.org/api/ng/service/$anchorScroll
Ответ 6
Вы можете добиться этого, используя пользовательский каталог углов.
пример:
<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>