我们依旧从界面及逻辑两块进行分析
1.界面上,只分成简单的两块,一块是上方的刷新文字,一块是下方的内容,然后将上方提示内容隐藏在屏幕之外,一般由两种方式,一种是上面遮一层,另一种是marginTop:负值将其弄出屏幕外,这里我采用的是第一种,代码也很简单,就随便贴一下
1 2 3 4 5 6
| .header{ width: 100%; height: 1rem;这里的高度应该与刷新文字一样高 position: fixed; z-index: 100; }
|
2.功能实现的重头戏是在逻辑上,主要分成下面几个部分
- 监听事件
- 位置计算
- 控制界面变化
- 数据更新包
- 我一个一个进行分析,然后带你们入坑。
监听事件,这块简单,直接贴代码
1 2 3 4 5 6 7 8 9 10
|
this.el.addEventListener('touchstart', this.refreshTouchStart); this.el.addEventListener('touchmove', this.refreshTouchMove); this.el.addEventListener('touchend', this.refreshTouchEnd);
this.el.removeEventListener('touchstart', this.refreshTouchStart); this.el.removeEventListener('touchmove', this.refreshTouchMovee); this.el.removeEventListener('touchend', this.refreshTouchEnd);
|
位置计算 我们分下拉刷新,上拉加载两块计算,分析可得
下拉刷新的逻辑 = 当前页面的首项在屏幕中且容器向下滑动的距离大于一定值
上拉加载的逻辑 = 当前页面已滑动到底部
好,我们直接看具体的实现逻辑代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| refreshTouchStart(e) { let touch = e.changedTouches[0]; this.tipText = '下拉刷新'; this.startY = touch.clientY; } refreshTouchMove(e) { this.$store.commit('bottomShowFalse'); let touch = e.changedTouches[0]; let _move = touch.clientY - this.startY; this.bottomFlag = $('.present-box').offset().top + $('.present-box').height() - document.body.clientHeight <= 40; if ($('.present-box').offset().top >= this.headerHeight) { if (_move > 0 && _move < 1000) { this.el.style.marginTop = _move + 'px'; this.moveDistance = touch.clientY - this.startY; if (_move > 50) { this.tipText = '松开即可刷新' } } } } refreshTouchEnd() { this.$store.commit('bottomShowTrue'); if (this.bottomFlag) { this.$emit('loadBottom'); } let that = this; if (this.moveDistance > 50) { this.tipText = '数据加载中...'; let timer = setInterval(function () { that.el.style.marginTop = that.el.style.marginTop.split('px')[0] - 5 + 'px'; if (Number(that.el.style.marginTop.split('px')[0]) <= 50) { clearInterval(timer); new Promise((resolve, reject) => { that.$emit('loadTop', resolve, reject); }).then(() => { that.resetBox(); }).catch(() => { that.resetBox(); }); } }, 1); } else { this.resetBox(); } } resetBox() { let that = this; if (this.moveDistance > 0) { let timer = setInterval(function () { that.el.style.marginTop = that.el.style.marginTop.split('px')[0] - 1 + 'px'; if (Number(that.el.style.marginTop.split('px')[0]) <= 0) { clearInterval(timer); } }, 1) } this.moveDistance = 0; }
|
效果图