Mis*_*hko 30 scroll angularjs angularjs-ng-repeat
使用的对象列表ng-repeat
.假设此列表非常长并且用户滚动到底部以查看某些对象.
当用户观察对象时,新项目将添加到列表顶部.这导致观察对象改变其位置,即用户突然在观察对象的相同位置看到其他东西.
当添加新项目时,您将如何将观察对象保持在同一位置?
art*_*iak 30
通过使用scrollTop
属性,它可以很优雅地解决div
.我使用了两个指令 - 一个处理包装元素的滚动位置,另一个指定新元素.如果有什么不清楚的话,请给我一个喊叫.
JS:
.directive("keepScroll", function(){
return {
controller : function($scope){
var element = null;
this.setElement = function(el){
element = el;
}
this.addItem = function(item){
console.log("Adding item", item, item.clientHeight);
element.scrollTop = (element.scrollTop+item.clientHeight+1);
//1px for margin from your css (surely it would be possible
// to make it more generic, rather then hard-coding the value)
};
},
link : function(scope,el,attr, ctrl) {
ctrl.setElement(el[0]);
}
};
})
.directive("scrollItem", function(){
return{
require : "^keepScroll",
link : function(scope, el, att, scrCtrl){
scrCtrl.addItem(el[0]);
}
}
})
Run Code Online (Sandbox Code Playgroud)
HTML:
<div class="wrapper" keep-scroll>
<div class="item" scroll-item ng-repeat="item in items | orderBy: '-id'">
{{ item.name }}
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
您知道其他人正在尝试使用不同的UI方法解决此问题.它们不只是在顶部突出显示新项目,而是在顶部显示一个小的可点击链接,说明自上次检查后添加了多少新项目.
[2 new items, Click here to refresh]
item 5
item 4
item 3
Run Code Online (Sandbox Code Playgroud)
看看twitter如何解决这个问题.
我知道这与你想要的东西有点矛盾,但也许这在UX方面更好?用户想知道是否有新物品进入.
您可以滚动添加元素的高度
$scope.addNewItem = function() {
var wrapper = document.getElementsByClassName('wrapper')[0];
$scope.items = $scope.items.concat({
id: $scope.items.length,
name: "item " + $scope.items.length
});
// will fail if you observe the item 0 because we scroll before the view is updated;
wrapper.scrollTop+=101; //height+margings+paddings
};
Run Code Online (Sandbox Code Playgroud)
我正在使用从控制器访问DOM的错误做法.更模块化的方法是创建一个指令,它将处理所有情况并在更新视图后更改滚动位置.
演示http://jsbin.com/zofofapo/8/edit
或者,对于项目不是同样高的情况,您可以看到插入前剩余多少滚动,并在插入后重新设置
$scope.addNewItem = function() {
var wrapper = document.getElementsByClassName('wrapper')[0],
scrollRemaining = wrapper.scrollHeight - wrapper.scrollTop;
$scope.items = $scope.items.concat({
id: $scope.items.length,
name: "item " + $scope.items.length
});
// will fail if you observe the item 0 because we scroll before the view is updated;
$timeout(function(){
wrapper.scrollTop = wrapper.scrollHeight - scrollRemaining;
},0);
};
Run Code Online (Sandbox Code Playgroud)
演示http://jsbin.com/zofofapo/9/edit
以下是对 Arthur 版本的改进,无论添加的项目是在滚动上方还是下方添加,都可以防止滚动: JS Bin
angular.module("Demo", [])
.controller("DemoCtrl", function($scope) {
$scope.items = [];
for (var i = 0; i < 10; i++) {
$scope.items[i] = {
id: i,
name: 'item ' + i
};
}
$scope.addNewItemTop = function() {
$scope.items.unshift({
id: $scope.items.length,
name: "item " + $scope.items.length
});
};
$scope.addNewItemMiddle = function() {
$scope.items.splice(5, 0, {
id: $scope.items.length,
name: "item " + $scope.items.length
});
};
$scope.addNewItemBottom = function() {
$scope.items = $scope.items.concat({
id: $scope.items.length,
name: "item " + $scope.items.length
});
};
})
.directive("keepScroll", function(){
return {
controller : function($scope){
var element = 0;
this.setElement = function(el){
element = el;
};
this.addItem = function(item){
console.group("Item");
console.log("OffsetTop: " + item.offsetTop);
console.log("ScrollTop: " + element.scrollTop);
if(item.offsetTop <= element.scrollTop) {
console.log("Adjusting scorlltop position");
element.scrollTop = (element.scrollTop+item.clientHeight+1); //1px for margin
} else {
console.log("Not adjusting scroll");
}
console.groupEnd("Item");
};
},
link : function(scope,el,attr, ctrl) {
ctrl.setElement(el[0]);
}
};
})
.directive("scrollItem", function(){
return{
require : "^keepScroll",
link : function(scope, el, att, scrCtrl){
scrCtrl.addItem(el[0]);
}
};
});
Run Code Online (Sandbox Code Playgroud)
.wrapper {
width: 200px;
height: 300px;
border: 1px solid black;
overflow: auto;
/* Required for correct offsetParent */
position: relative;
}
.item {
background-color: #ccc;
height: 100px;
margin-bottom: 1px;
}
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html>
<head>
<script src="//code.angularjs.org/1.3.0-beta.7/angular.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body ng-app="Demo" ng-controller="DemoCtrl">
<div class="wrapper" keep-scroll>
<div class="item" scroll-item ng-repeat="item in items">
{{ item.name }}
</div>
</div>
<button ng-click="addNewItemTop()">
Add New Item Top
</button>
<button ng-click="addNewItemMiddle()">
Add New Item Middle
</button>
<button ng-click="addNewItemBottom()">
Add New Item Bottom
</button>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
25311 次 |
最近记录: |