常见开发需求之angular上拉加载更多
需求
移动端使用angular实现上拉加载更多的条目,这个需求比较常见,网上的插件改动起来比较麻烦,不如自己写一个最适合,以前有同事写了一个,奈何bug太多,后来改分页了,我们产品说什么都让做,没办法,只能自己动手写一下,需要自定义指令,我的思路就是当页面第一次加载的时候我们先固定请求一部分数据进行显示,之后使用js探测垂直滚动条的滚动距离,当页面即将触底的时候发送第n+1请求,为防止在请求过程中重复请求加入了截流判断,其次在请求过程中页面最底部出现加载等待动画。如图所示
指令实现
// isBottom为防止滚动多次触发,用于截流。
// $scope.infinite_isCmp用于控制“正在加载……”的显示与隐藏,可以为这个标签添加css3动画,达到如图所示效果
XXXDirectives.directive("infiniteScroll", [function () {
return {
controller: "infiniteScroll_controller"
};
}]);
XXXDirectives.controller("infiniteScroll_controller", ["$timeout",function ($timeout) {
var isBottom = false;
$scope.infinite_isCmp = false;
//将此处改为第一次请求数据
aa.require().success(function (data) {
$scope.data = data;
});
//获得元素
var wai = $window.document.getElementById("外层滚动容器wai");
var content = $window.document.getElementById("承载内容列表content");
//监听滚动
wai.onscroll = function () {
var scrollTop = wai.scrollTop,
viewHeight = wai.clientHeight,
height = content.offsetHeight;
//判断是否滚动到底部
if (((scrollTop + viewHeight) >= height) && !isBottom)
{
isBottom = true;
console.log("到底了");
$scope.infinite_isCmp = true;
$scope.$apply();
$rootScope.requireCount+=10;
//模拟请求延时,将第二次延时2s后
$timeout(function () {
aaa.require().success(function (data) {
$scope.model = data;
isBottom = false;
$scope.infinite_isCmp = false;
});
},2000);
}
}
}]);
html部分代码
<div id="wai">
<div id="content">
<infinite-scroll>
//循环li
<li ng-repeat=""></li>
//是否出现加载状态
<div ng-show="infinite_isCmp"></div>
</infinite-scroll>
</div>
</div>
原理
监听最外层容器的滚动,当滚动条scrollTop加上容器视口的高度大于或等于内部承载内容的容器则代表需要开始加载,获取dom元素请大家自行修改。
结尾及使用
将以上代码的第一次和第二次请求处分别填入要请求的地址,使用<infinite-scroll>标签包裹需要滚动的内容即可,如果需要底部加载动画的,请为infinite_isCmp增加class样式,程序有很多不完善的方面,代码解耦因为时间关系做的不到位,不过应对产品的催时间和完成效果是足够了。