需求
移動端使用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樣式,程序有很多不完善的方面,代碼解耦因為時間關系做的不到位,不過應對產品的催時間和完成效果是足夠了。
