better-scroll:angularJs中用better-scroll封裝一個滾動的指令

注:ionic自帶的ion-scrll,在添加了一個長按複製的類樣式後,會致使滾動白屏的問題。由於長按複製的類阻礙了ionic的滑動監聽事件。因此選擇用better-scroll來代替ionic的滾動效果。android

 

import BScroll from 'better-scroll';

// @ngInject
function ikScroll($timeout, $compile) {
function initPullDown(bScroll, $scope, $element) {
// 是否開啓回彈
let isRebounding = false;
const initTop = -60;
const initDown = {
top: `${initTop}px`,
before: true,
isFlip: false,
};
const $pullDown = angular.element(`
<div class="ik-scroll-pull-down" ng-style="{top:down.top}">
<div class="ik-scroll-pull-down-icon" ng-if="down.before">
<i class="icon ion-android-arrow-down" ng-class="{flip:down.isFlip}"></i>
</div>

<div class="ik-scroll-pull-down-loading" ng-if="!down.before">
<ion-spinner icon="ios"></ion-spinner>
</div>
</div>
`);

$element.append($compile($pullDown)($scope));
$scope.down = _.assign({}, initDown);

bScroll.on('pullingDown', () => {
$scope.$apply(() => {
$scope.down.before = false;
});

$scope.onPullDown().then(() => {
isRebounding = true;
bScroll.finishPullDown();

$timeout(() => {
$scope.down = _.assign({}, initDown);
isRebounding = false;
bScroll.refresh();
}, bScroll.options.bounceTime);
});
});

bScroll.on('scroll', (pos) => {
$scope.$apply(() => {
if ($scope.down.before) {
$scope.down.top = `${Math.min(pos.y + initTop, 0)}px`;
}

if (pos.y >= 60) {
$scope.down.isFlip = true;
}

if (isRebounding) {
$scope.down.top = `${0 - (60 - pos.y)}px`;
}
});
});
}

function initPullUp(bScroll, $scope, $content) {
const $pullUp = angular.element(`
<div class="ik-scroll-pull-up">
<div class="ik-scroll-pull-up-text" ng-style="{display:up.textDisplay}">{{up.text}}</div>
<div class="ik-scroll-pull-up-loading" ng-if="up.loading">
<ion-spinner icon="ios"></ion-spinner>
</div>
</div>
`);
$content.append($compile($pullUp)($scope));

$scope.up = {
loading: false,
text: '加載更多',
textDisplay: 'block',
};

$scope.up.text = $scope.moreData ? '加載更多' : '沒有更多數據了~';
bScroll.on('pullingUp', () => {
const result = $scope.onPullUp();

$scope.$apply(() => {
$scope.up.loading = true;
$scope.up.textDisplay = 'none';

if (!result) {
$scope.up.loading = false;
$scope.up.text = '沒有更多數據了~';
$scope.up.textDisplay = 'block';

bScroll.finishPullUp();
} else {
result.then(() => {
$timeout(() => {
$scope.up.loading = false;
$scope.up.text = '加載更多';
$scope.up.textDisplay = 'block';

bScroll.finishPullUp();
bScroll.refresh();
});
});
}
});
});
}

return {
restrict: 'E',
scope: {
onPullDown: '&',
onPullUp: '&',
moreData: '='
},
compile: ($element) => {
$element.addClass('ik-scroll');

const $content = angular.element('<div class="ik-scroll-content"></div>');
$content.append($element.contents());
$element.append($content);

return ($scope, $element, $attrs) => {
const opts = {
scrollbar: { fade: true },
preventDefaultException: {className:/(^|\s)long-tap--copy(\s|$)/},
};

// 是否開啓下拉刷新
if ($attrs.onPullDown) {
opts.pullDownRefresh = { threshold: 60, stop: 60 };
}

// 是否開啓上拉加載
if ($attrs.onPullUp) {
opts.pullUpLoad = { threshold: 60 };
}

$timeout(() => {
const bScroll = new BScroll($element[0], opts);

if ($attrs.onPullDown) {
initPullDown(bScroll, $scope, $element);
}

if ($attrs.onPullUp) {
initPullUp(bScroll, $scope, $content);
}
});
};
},
};
}

export default ikScroll;
相關文章
相關標籤/搜索