|
@@ -0,0 +1,799 @@
|
|
|
+
|
|
|
+ * version 1.3.3
|
|
|
+ * 2020-09-15 wenju
|
|
|
+ * https:
|
|
|
+ */
|
|
|
+
|
|
|
+export default function MeScroll(options, isScrollBody) {
|
|
|
+ let me = this;
|
|
|
+ me.version = '1.3.3';
|
|
|
+ me.options = options || {};
|
|
|
+ me.isScrollBody = isScrollBody || false;
|
|
|
+
|
|
|
+ me.isDownScrolling = false;
|
|
|
+ me.isUpScrolling = false;
|
|
|
+ let hasDownCallback = me.options.down && me.options.down.callback;
|
|
|
+
|
|
|
+
|
|
|
+ me.initDownScroll();
|
|
|
+
|
|
|
+ me.initUpScroll();
|
|
|
+
|
|
|
+
|
|
|
+ setTimeout(function() {
|
|
|
+
|
|
|
+ if ((me.optDown.use || me.optDown.native) && me.optDown.auto && hasDownCallback) {
|
|
|
+ if (me.optDown.autoShowLoading) {
|
|
|
+ me.triggerDownScroll();
|
|
|
+ } else {
|
|
|
+ me.optDown.callback && me.optDown.callback(me);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!me.isUpAutoLoad){
|
|
|
+ setTimeout(function(){
|
|
|
+ me.optUp.use && me.optUp.auto && !me.isUpAutoLoad && me.triggerUpScroll();
|
|
|
+ },100)
|
|
|
+ }
|
|
|
+ }, 30);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.extendDownScroll = function(optDown) {
|
|
|
+
|
|
|
+ MeScroll.extend(optDown, {
|
|
|
+ use: true,
|
|
|
+ auto: true,
|
|
|
+ native: false,
|
|
|
+ autoShowLoading: false,
|
|
|
+ isLock: false,
|
|
|
+ offset: 80,
|
|
|
+ startTop: 100,
|
|
|
+ inOffsetRate: 1,
|
|
|
+ outOffsetRate: 0.2,
|
|
|
+ bottomOffset: 20,
|
|
|
+ minAngle: 45,
|
|
|
+ textInOffset: '下拉刷新',
|
|
|
+ textOutOffset: '释放更新',
|
|
|
+ textLoading: '加载中 ...',
|
|
|
+ textSuccess: '加载成功',
|
|
|
+ textErr: '加载失败',
|
|
|
+ beforeEndDelay: 100,
|
|
|
+ bgColor: "transparent",
|
|
|
+ textColor: "gray",
|
|
|
+ inited: null,
|
|
|
+ inOffset: null,
|
|
|
+ outOffset: null,
|
|
|
+ onMoving: null,
|
|
|
+ beforeLoading: null,
|
|
|
+ showLoading: null,
|
|
|
+ afterLoading: null,
|
|
|
+ beforeEndDownScroll: null,
|
|
|
+ endDownScroll: null,
|
|
|
+ afterEndDownScroll: null,
|
|
|
+ callback: function(mescroll) {
|
|
|
+
|
|
|
+ mescroll.resetUpScroll();
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.extendUpScroll = function(optUp) {
|
|
|
+
|
|
|
+ MeScroll.extend(optUp, {
|
|
|
+ use: true,
|
|
|
+ auto: true,
|
|
|
+ isLock: false,
|
|
|
+ isBoth: true,
|
|
|
+ callback: null,
|
|
|
+ page: {
|
|
|
+ num: 0,
|
|
|
+ size: 10,
|
|
|
+ time: null
|
|
|
+ },
|
|
|
+ noMoreSize: 5,
|
|
|
+ offset: 150,
|
|
|
+ textLoading: '加载中 ...',
|
|
|
+ textNoMore: '-- END --',
|
|
|
+ bgColor: "transparent",
|
|
|
+ textColor: "gray",
|
|
|
+ inited: null,
|
|
|
+ showLoading: null,
|
|
|
+ showNoMore: null,
|
|
|
+ hideUpScroll: null,
|
|
|
+ errDistance: 60,
|
|
|
+ toTop: {
|
|
|
+
|
|
|
+ src: null,
|
|
|
+ offset: 1000,
|
|
|
+ duration: 300,
|
|
|
+ btnClick: null,
|
|
|
+ onShow: null,
|
|
|
+ zIndex: 9990,
|
|
|
+ left: null,
|
|
|
+ right: 20,
|
|
|
+ bottom: 120,
|
|
|
+ safearea: false,
|
|
|
+ width: 72,
|
|
|
+ radius: "50%"
|
|
|
+ },
|
|
|
+ empty: {
|
|
|
+ use: true,
|
|
|
+ icon: null,
|
|
|
+ tip: '~ 暂无相关数据 ~',
|
|
|
+ btnText: '',
|
|
|
+ btnClick: null,
|
|
|
+ onShow: null,
|
|
|
+ fixed: false,
|
|
|
+ top: "100rpx",
|
|
|
+ zIndex: 99
|
|
|
+ },
|
|
|
+ onScroll: false
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.extend = function(userOption, defaultOption) {
|
|
|
+ if (!userOption) return defaultOption;
|
|
|
+ for (let key in defaultOption) {
|
|
|
+ if (userOption[key] == null) {
|
|
|
+ let def = defaultOption[key];
|
|
|
+ if (def != null && typeof def === 'object') {
|
|
|
+ userOption[key] = MeScroll.extend({}, def);
|
|
|
+ } else {
|
|
|
+ userOption[key] = def;
|
|
|
+ }
|
|
|
+ } else if (typeof userOption[key] === 'object') {
|
|
|
+ MeScroll.extend(userOption[key], defaultOption[key]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return userOption;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.hasColor = function(color) {
|
|
|
+ if(!color) return false;
|
|
|
+ let c = color.toLowerCase();
|
|
|
+ return c != "#fff" && c != "#ffffff" && c != "transparent" && c != "white"
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.initDownScroll = function() {
|
|
|
+ let me = this;
|
|
|
+
|
|
|
+ me.optDown = me.options.down || {};
|
|
|
+ if(!me.optDown.textColor && me.hasColor(me.optDown.bgColor)) me.optDown.textColor = "#fff";
|
|
|
+ me.extendDownScroll(me.optDown);
|
|
|
+
|
|
|
+
|
|
|
+ if(me.isScrollBody && me.optDown.native){
|
|
|
+ me.optDown.use = false
|
|
|
+ }else{
|
|
|
+ me.optDown.native = false
|
|
|
+ }
|
|
|
+
|
|
|
+ me.downHight = 0;
|
|
|
+
|
|
|
+
|
|
|
+ if (me.optDown.use && me.optDown.inited) {
|
|
|
+
|
|
|
+ setTimeout(function() {
|
|
|
+ me.optDown.inited(me);
|
|
|
+ }, 0)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.touchstartEvent = function(e) {
|
|
|
+ if (!this.optDown.use) return;
|
|
|
+
|
|
|
+ this.startPoint = this.getPoint(e);
|
|
|
+ this.startTop = this.getScrollTop();
|
|
|
+ this.startAngle = 0;
|
|
|
+ this.lastPoint = this.startPoint;
|
|
|
+ this.maxTouchmoveY = this.getBodyHeight() - this.optDown.bottomOffset;
|
|
|
+ this.inTouchend = false;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.touchmoveEvent = function(e) {
|
|
|
+ if (!this.optDown.use) return;
|
|
|
+ let me = this;
|
|
|
+
|
|
|
+ let scrollTop = me.getScrollTop();
|
|
|
+ let curPoint = me.getPoint(e);
|
|
|
+
|
|
|
+ let moveY = curPoint.y - me.startPoint.y;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (moveY > 0 && (
|
|
|
+ (me.isScrollBody && scrollTop <= 0)
|
|
|
+ ||
|
|
|
+ (!me.isScrollBody && (scrollTop <= 0 || (scrollTop <= me.optDown.startTop && scrollTop === me.startTop)) )
|
|
|
+ )) {
|
|
|
+
|
|
|
+ if (!me.inTouchend && !me.isDownScrolling && !me.optDown.isLock && (!me.isUpScrolling || (me.isUpScrolling &&
|
|
|
+ me.optUp.isBoth))) {
|
|
|
+
|
|
|
+
|
|
|
+ if(!me.startAngle) me.startAngle = me.getAngle(me.lastPoint, curPoint);
|
|
|
+ if (me.startAngle < me.optDown.minAngle) return;
|
|
|
+
|
|
|
+
|
|
|
+ if (me.maxTouchmoveY > 0 && curPoint.y >= me.maxTouchmoveY) {
|
|
|
+ me.inTouchend = true;
|
|
|
+ me.touchendEvent();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ me.preventDefault(e);
|
|
|
+
|
|
|
+ let diff = curPoint.y - me.lastPoint.y;
|
|
|
+
|
|
|
+
|
|
|
+ if (me.downHight < me.optDown.offset) {
|
|
|
+ if (me.movetype !== 1) {
|
|
|
+ me.movetype = 1;
|
|
|
+ me.isDownEndSuccess = null;
|
|
|
+ me.optDown.inOffset && me.optDown.inOffset(me);
|
|
|
+ me.isMoveDown = true;
|
|
|
+ }
|
|
|
+ me.downHight += diff * me.optDown.inOffsetRate;
|
|
|
+
|
|
|
+
|
|
|
+ } else {
|
|
|
+ if (me.movetype !== 2) {
|
|
|
+ me.movetype = 2;
|
|
|
+ me.optDown.outOffset && me.optDown.outOffset(me);
|
|
|
+ me.isMoveDown = true;
|
|
|
+ }
|
|
|
+ if (diff > 0) {
|
|
|
+ me.downHight += diff * me.optDown.outOffsetRate;
|
|
|
+ } else {
|
|
|
+ me.downHight += diff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ me.downHight = Math.round(me.downHight)
|
|
|
+ let rate = me.downHight / me.optDown.offset;
|
|
|
+ me.optDown.onMoving && me.optDown.onMoving(me, rate, me.downHight);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ me.lastPoint = curPoint;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.touchendEvent = function(e) {
|
|
|
+ if (!this.optDown.use) return;
|
|
|
+
|
|
|
+ if (this.isMoveDown) {
|
|
|
+ if (this.downHight >= this.optDown.offset) {
|
|
|
+
|
|
|
+ this.triggerDownScroll();
|
|
|
+ } else {
|
|
|
+
|
|
|
+ this.downHight = 0;
|
|
|
+ this.endDownScrollCall(this);
|
|
|
+ }
|
|
|
+ this.movetype = 0;
|
|
|
+ this.isMoveDown = false;
|
|
|
+ } else if (!this.isScrollBody && this.getScrollTop() === this.startTop) {
|
|
|
+ let isScrollUp = this.getPoint(e).y - this.startPoint.y < 0;
|
|
|
+
|
|
|
+ if (isScrollUp) {
|
|
|
+
|
|
|
+ let angle = this.getAngle(this.getPoint(e), this.startPoint);
|
|
|
+ if (angle > 80) {
|
|
|
+
|
|
|
+ this.triggerUpScroll(true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.getPoint = function(e) {
|
|
|
+ if (!e) {
|
|
|
+ return {
|
|
|
+ x: 0,
|
|
|
+ y: 0
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (e.touches && e.touches[0]) {
|
|
|
+ return {
|
|
|
+ x: e.touches[0].pageX,
|
|
|
+ y: e.touches[0].pageY
|
|
|
+ }
|
|
|
+ } else if (e.changedTouches && e.changedTouches[0]) {
|
|
|
+ return {
|
|
|
+ x: e.changedTouches[0].pageX,
|
|
|
+ y: e.changedTouches[0].pageY
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return {
|
|
|
+ x: e.clientX,
|
|
|
+ y: e.clientY
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.getAngle = function(p1, p2) {
|
|
|
+ let x = Math.abs(p1.x - p2.x);
|
|
|
+ let y = Math.abs(p1.y - p2.y);
|
|
|
+ let z = Math.sqrt(x * x + y * y);
|
|
|
+ let angle = 0;
|
|
|
+ if (z !== 0) {
|
|
|
+ angle = Math.asin(y / z) / Math.PI * 180;
|
|
|
+ }
|
|
|
+ return angle
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.triggerDownScroll = function() {
|
|
|
+ if (this.optDown.beforeLoading && this.optDown.beforeLoading(this)) {
|
|
|
+
|
|
|
+ } else {
|
|
|
+ this.showDownScroll();
|
|
|
+ !this.optDown.native && this.optDown.callback && this.optDown.callback(this);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.showDownScroll = function() {
|
|
|
+ this.isDownScrolling = true;
|
|
|
+ if (this.optDown.native) {
|
|
|
+ uni.startPullDownRefresh();
|
|
|
+ this.showDownLoadingCall(0);
|
|
|
+ } else{
|
|
|
+ this.downHight = this.optDown.offset;
|
|
|
+ this.showDownLoadingCall(this.downHight);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+MeScroll.prototype.showDownLoadingCall = function(downHight) {
|
|
|
+ this.optDown.showLoading && this.optDown.showLoading(this, downHight);
|
|
|
+ this.optDown.afterLoading && this.optDown.afterLoading(this, downHight);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.onPullDownRefresh = function() {
|
|
|
+ this.isDownScrolling = true;
|
|
|
+ this.showDownLoadingCall(0);
|
|
|
+ this.optDown.callback && this.optDown.callback(this);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.endDownScroll = function() {
|
|
|
+ if (this.optDown.native) {
|
|
|
+ this.isDownScrolling = false;
|
|
|
+ this.endDownScrollCall(this);
|
|
|
+ uni.stopPullDownRefresh();
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let me = this;
|
|
|
+
|
|
|
+ let endScroll = function() {
|
|
|
+ me.downHight = 0;
|
|
|
+ me.isDownScrolling = false;
|
|
|
+ me.endDownScrollCall(me);
|
|
|
+ if(!me.isScrollBody){
|
|
|
+ me.setScrollHeight(0)
|
|
|
+ me.scrollTo(0,0)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let delay = 0;
|
|
|
+ if (me.optDown.beforeEndDownScroll) {
|
|
|
+ delay = me.optDown.beforeEndDownScroll(me);
|
|
|
+ if(me.isDownEndSuccess == null) delay = 0;
|
|
|
+ }
|
|
|
+ if (typeof delay === 'number' && delay > 0) {
|
|
|
+ setTimeout(endScroll, delay);
|
|
|
+ } else {
|
|
|
+ endScroll();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+MeScroll.prototype.endDownScrollCall = function() {
|
|
|
+ this.optDown.endDownScroll && this.optDown.endDownScroll(this);
|
|
|
+ this.optDown.afterEndDownScroll && this.optDown.afterEndDownScroll(this);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.lockDownScroll = function(isLock) {
|
|
|
+ if (isLock == null) isLock = true;
|
|
|
+ this.optDown.isLock = isLock;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.lockUpScroll = function(isLock) {
|
|
|
+ if (isLock == null) isLock = true;
|
|
|
+ this.optUp.isLock = isLock;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.initUpScroll = function() {
|
|
|
+ let me = this;
|
|
|
+
|
|
|
+ me.optUp = me.options.up || {use: false}
|
|
|
+ if(!me.optUp.textColor && me.hasColor(me.optUp.bgColor)) me.optUp.textColor = "#fff";
|
|
|
+ me.extendUpScroll(me.optUp);
|
|
|
+
|
|
|
+ if (me.optUp.use === false) return;
|
|
|
+ me.optUp.hasNext = true;
|
|
|
+ me.startNum = me.optUp.page.num + 1;
|
|
|
+
|
|
|
+
|
|
|
+ if (me.optUp.inited) {
|
|
|
+ setTimeout(function() {
|
|
|
+ me.optUp.inited(me);
|
|
|
+ }, 0)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.onReachBottom = function() {
|
|
|
+ if (this.isScrollBody && !this.isUpScrolling) {
|
|
|
+ if (!this.optUp.isLock && this.optUp.hasNext) {
|
|
|
+ this.triggerUpScroll();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.onPageScroll = function(e) {
|
|
|
+ if (!this.isScrollBody) return;
|
|
|
+
|
|
|
+
|
|
|
+ this.setScrollTop(e.scrollTop);
|
|
|
+
|
|
|
+
|
|
|
+ if (e.scrollTop >= this.optUp.toTop.offset) {
|
|
|
+ this.showTopBtn();
|
|
|
+ } else {
|
|
|
+ this.hideTopBtn();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.scroll = function(e, onScroll) {
|
|
|
+
|
|
|
+ this.setScrollTop(e.scrollTop);
|
|
|
+
|
|
|
+ this.setScrollHeight(e.scrollHeight);
|
|
|
+
|
|
|
+
|
|
|
+ if (this.preScrollY == null) this.preScrollY = 0;
|
|
|
+ this.isScrollUp = e.scrollTop - this.preScrollY > 0;
|
|
|
+ this.preScrollY = e.scrollTop;
|
|
|
+
|
|
|
+
|
|
|
+ this.isScrollUp && this.triggerUpScroll(true);
|
|
|
+
|
|
|
+
|
|
|
+ if (e.scrollTop >= this.optUp.toTop.offset) {
|
|
|
+ this.showTopBtn();
|
|
|
+ } else {
|
|
|
+ this.hideTopBtn();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ this.optUp.onScroll && onScroll && onScroll()
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.triggerUpScroll = function(isCheck) {
|
|
|
+ if (!this.isUpScrolling && this.optUp.use && this.optUp.callback) {
|
|
|
+
|
|
|
+ if (isCheck === true) {
|
|
|
+ let canUp = false;
|
|
|
+
|
|
|
+ if (this.optUp.hasNext && !this.optUp.isLock && !this.isDownScrolling) {
|
|
|
+ if (this.getScrollBottom() <= this.optUp.offset) {
|
|
|
+ canUp = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (canUp === false) return;
|
|
|
+ }
|
|
|
+ this.showUpScroll();
|
|
|
+ this.optUp.page.num++;
|
|
|
+ this.isUpAutoLoad = true;
|
|
|
+ this.num = this.optUp.page.num;
|
|
|
+ this.size = this.optUp.page.size;
|
|
|
+ this.time = this.optUp.page.time;
|
|
|
+ this.optUp.callback(this);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.showUpScroll = function() {
|
|
|
+ this.isUpScrolling = true;
|
|
|
+ this.optUp.showLoading && this.optUp.showLoading(this);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.showNoMore = function() {
|
|
|
+ this.optUp.hasNext = false;
|
|
|
+ this.optUp.showNoMore && this.optUp.showNoMore(this);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.hideUpScroll = function() {
|
|
|
+ this.optUp.hideUpScroll && this.optUp.hideUpScroll(this);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.endUpScroll = function(isShowNoMore) {
|
|
|
+ if (isShowNoMore != null) {
|
|
|
+ if (isShowNoMore) {
|
|
|
+ this.showNoMore();
|
|
|
+ } else {
|
|
|
+ this.hideUpScroll();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.isUpScrolling = false;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ *isShowLoading 是否显示进度布局;
|
|
|
+ * 1.默认null,不传参,则显示上拉加载的进度布局
|
|
|
+ * 2.传参true, 则显示下拉刷新的进度布局
|
|
|
+ * 3.传参false,则不显示上拉和下拉的进度 (常用于静默更新列表数据)
|
|
|
+ */
|
|
|
+MeScroll.prototype.resetUpScroll = function(isShowLoading) {
|
|
|
+ if (this.optUp && this.optUp.use) {
|
|
|
+ let page = this.optUp.page;
|
|
|
+ this.prePageNum = page.num;
|
|
|
+ this.prePageTime = page.time;
|
|
|
+ page.num = this.startNum;
|
|
|
+ page.time = null;
|
|
|
+ if (!this.isDownScrolling && isShowLoading !== false) {
|
|
|
+ if (isShowLoading == null) {
|
|
|
+ this.removeEmpty();
|
|
|
+ this.showUpScroll();
|
|
|
+ } else {
|
|
|
+ this.showDownScroll();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.isUpAutoLoad = true;
|
|
|
+ this.num = page.num;
|
|
|
+ this.size = page.size;
|
|
|
+ this.time = page.time;
|
|
|
+ this.optUp.callback && this.optUp.callback(this);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.setPageNum = function(num) {
|
|
|
+ this.optUp.page.num = num - 1;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.setPageSize = function(size) {
|
|
|
+ this.optUp.page.size = size;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * dataSize: 当前页的数据量(必传)
|
|
|
+ * totalPage: 总页数(必传)
|
|
|
+ * systime: 服务器时间 (可空)
|
|
|
+ */
|
|
|
+MeScroll.prototype.endByPage = function(dataSize, totalPage, systime) {
|
|
|
+ let hasNext;
|
|
|
+ if (this.optUp.use && totalPage != null) hasNext = this.optUp.page.num < totalPage;
|
|
|
+ this.endSuccess(dataSize, hasNext, systime);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * dataSize: 当前页的数据量(必传)
|
|
|
+ * totalSize: 列表所有数据总数量(必传)
|
|
|
+ * systime: 服务器时间 (可空)
|
|
|
+ */
|
|
|
+MeScroll.prototype.endBySize = function(dataSize, totalSize, systime) {
|
|
|
+ let hasNext;
|
|
|
+ if (this.optUp.use && totalSize != null) {
|
|
|
+ let loadSize = (this.optUp.page.num - 1) * this.optUp.page.size + dataSize;
|
|
|
+ hasNext = loadSize < totalSize;
|
|
|
+ }
|
|
|
+ this.endSuccess(dataSize, hasNext, systime);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * dataSize: 当前页的数据个数(不是所有页的数据总和),用于上拉加载判断是否还有下一页.如果不传,则会判断还有下一页
|
|
|
+ * hasNext: 是否还有下一页,布尔类型;用来解决这个小问题:比如列表共有20条数据,每页加载10条,共2页.如果只根据dataSize判断,则需翻到第三页才会知道无更多数据,如果传了hasNext,则翻到第二页即可显示无更多数据.
|
|
|
+ * systime: 服务器时间(可空);用来解决这个小问题:当准备翻下一页时,数据库新增了几条记录,此时翻下一页,前面的几条数据会和上一页的重复;这里传入了systime,那么upCallback的page.time就会有值,把page.time传给服务器,让后台过滤新加入的那几条记录
|
|
|
+ */
|
|
|
+MeScroll.prototype.endSuccess = function(dataSize, hasNext, systime) {
|
|
|
+ let me = this;
|
|
|
+
|
|
|
+ if (me.isDownScrolling) {
|
|
|
+ me.isDownEndSuccess = true
|
|
|
+ me.endDownScroll();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (me.optUp.use) {
|
|
|
+ let isShowNoMore;
|
|
|
+ if (dataSize != null) {
|
|
|
+ let pageNum = me.optUp.page.num;
|
|
|
+ let pageSize = me.optUp.page.size;
|
|
|
+
|
|
|
+ if (pageNum === 1) {
|
|
|
+ if (systime) me.optUp.page.time = systime;
|
|
|
+ }
|
|
|
+ if (dataSize < pageSize || hasNext === false) {
|
|
|
+
|
|
|
+ me.optUp.hasNext = false;
|
|
|
+ if (dataSize === 0 && pageNum === 1) {
|
|
|
+
|
|
|
+ isShowNoMore = false;
|
|
|
+ me.showEmpty();
|
|
|
+ } else {
|
|
|
+
|
|
|
+ let allDataSize = (pageNum - 1) * pageSize + dataSize;
|
|
|
+ if (allDataSize < me.optUp.noMoreSize) {
|
|
|
+ isShowNoMore = false;
|
|
|
+ } else {
|
|
|
+ isShowNoMore = true;
|
|
|
+ }
|
|
|
+ me.removeEmpty();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+
|
|
|
+ isShowNoMore = false;
|
|
|
+ me.optUp.hasNext = true;
|
|
|
+ me.removeEmpty();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ me.endUpScroll(isShowNoMore);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.endErr = function(errDistance) {
|
|
|
+
|
|
|
+ if (this.isDownScrolling) {
|
|
|
+ this.isDownEndSuccess = false
|
|
|
+ let page = this.optUp.page;
|
|
|
+ if (page && this.prePageNum) {
|
|
|
+ page.num = this.prePageNum;
|
|
|
+ page.time = this.prePageTime;
|
|
|
+ }
|
|
|
+ this.endDownScroll();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.isUpScrolling) {
|
|
|
+ this.optUp.page.num--;
|
|
|
+ this.endUpScroll(false);
|
|
|
+
|
|
|
+ if(this.isScrollBody && errDistance !== 0){
|
|
|
+ if(!errDistance) errDistance = this.optUp.errDistance;
|
|
|
+ this.scrollTo(this.getScrollTop() - errDistance, 0)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.showEmpty = function() {
|
|
|
+ this.optUp.empty.use && this.optUp.empty.onShow && this.optUp.empty.onShow(true)
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.removeEmpty = function() {
|
|
|
+ this.optUp.empty.use && this.optUp.empty.onShow && this.optUp.empty.onShow(false)
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.showTopBtn = function() {
|
|
|
+ if (!this.topBtnShow) {
|
|
|
+ this.topBtnShow = true;
|
|
|
+ this.optUp.toTop.onShow && this.optUp.toTop.onShow(true);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.hideTopBtn = function() {
|
|
|
+ if (this.topBtnShow) {
|
|
|
+ this.topBtnShow = false;
|
|
|
+ this.optUp.toTop.onShow && this.optUp.toTop.onShow(false);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.getScrollTop = function() {
|
|
|
+ return this.scrollTop || 0
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.setScrollTop = function(y) {
|
|
|
+ this.scrollTop = y;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.scrollTo = function(y, t) {
|
|
|
+ this.myScrollTo && this.myScrollTo(y, t)
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.resetScrollTo = function(myScrollTo) {
|
|
|
+ this.myScrollTo = myScrollTo
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.getScrollBottom = function() {
|
|
|
+ return this.getScrollHeight() - this.getClientHeight() - this.getScrollTop()
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ star: 开始值
|
|
|
+ end: 结束值
|
|
|
+ callback(step,timer): 回调step值,计步器timer,可自行通过window.clearInterval(timer)结束计步器;
|
|
|
+ t: 计步时长,传0则直接回调end值;不传则默认300ms
|
|
|
+ rate: 周期;不传则默认30ms计步一次
|
|
|
+ * */
|
|
|
+MeScroll.prototype.getStep = function(star, end, callback, t, rate) {
|
|
|
+ let diff = end - star;
|
|
|
+ if (t === 0 || diff === 0) {
|
|
|
+ callback && callback(end);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ t = t || 300;
|
|
|
+ rate = rate || 30;
|
|
|
+ let count = t / rate;
|
|
|
+ let step = diff / count;
|
|
|
+ let i = 0;
|
|
|
+ let timer = setInterval(function() {
|
|
|
+ if (i < count - 1) {
|
|
|
+ star += step;
|
|
|
+ callback && callback(star, timer);
|
|
|
+ i++;
|
|
|
+ } else {
|
|
|
+ callback && callback(end, timer);
|
|
|
+ clearInterval(timer);
|
|
|
+ }
|
|
|
+ }, rate);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.getClientHeight = function(isReal) {
|
|
|
+ let h = this.clientHeight || 0
|
|
|
+ if (h === 0 && isReal !== true) {
|
|
|
+ h = this.getBodyHeight()
|
|
|
+ }
|
|
|
+ return h
|
|
|
+}
|
|
|
+MeScroll.prototype.setClientHeight = function(h) {
|
|
|
+ this.clientHeight = h;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.getScrollHeight = function() {
|
|
|
+ return this.scrollHeight || 0;
|
|
|
+}
|
|
|
+MeScroll.prototype.setScrollHeight = function(h) {
|
|
|
+ this.scrollHeight = h;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.getBodyHeight = function() {
|
|
|
+ return this.bodyHeight || 0;
|
|
|
+}
|
|
|
+MeScroll.prototype.setBodyHeight = function(h) {
|
|
|
+ this.bodyHeight = h;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+MeScroll.prototype.preventDefault = function(e) {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (e && e.cancelable && !e.defaultPrevented) e.preventDefault()
|
|
|
+}
|