wuliu_sy/components/you-scroll.vue

272 lines
5.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="you-scroll" ref="youScroll">
<view class="pullDown" :style="{ transform: 'translateY('+translateY+'px)', transition: isDown ? '0s' : '0.3s' }">
<slot name="pullDown">
<!-- <img src="@/static/pullDown.jpg" :class="{'down-icon': true,'animate': pullDownStatus == 3}"></img> -->
<span>
<block v-if="pullDownStatus == 1">{{downPullToRefresh}}</block>
<block v-if="pullDownStatus == 2">{{downReleaseToRefresh}}</block>
<block v-if="pullDownStatus == 3">{{downRefreshing}}</block>
</span>
</slot>
</view>
<scroll-view class="you-scroll-inner" ref="youScrollInner" :scroll-top="scrollToTop" scroll-with-animation scroll-y :style="{ transform: 'translateY('+translateY+'px)', transition: isDown ? '0s' : 'transform 0.3s' }"
@touchstart="startFn" @touchmove="moveFn" @touchend="endFn" @touchcancel="endFn" @scroll="scroll">
<view class="you-scroll-content">
<slot></slot>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {
scrollToTop: 0,
scrollTop: 0,
oldTop: 0,
sPageY: 0,
mPageY: 0,
ePageY: 0,
translateY: 0,
pullDownStatus: 1, // 1下拉刷新 2松开刷新 3刷新中
isDown: false
};
},
props: {
pullDownDistance: {
type: Number,
default: 50 // 下拉刷新距离
},
reachBottomDistance: {
type: Number,
default: 30 // 上拉加载距离
},
downPullToRefresh: {
type: String,
default: '下拉刷新'
},
downReleaseToRefresh: {
type: String,
default: '松开刷新'
},
downRefreshing: {
type: String,
default: '刷新中…'
},
},
methods: {
startFn(e) {
this.isDown = true;
this.sPageY = e.changedTouches[0].pageY;
this.pointY = this.translateY;
},
moveFn(e) {
let view = uni.createSelectorQuery().in(this).select(".you-scroll-inner");
view.fields({
size: true,
scrollOffset: true
}, data => {
this.scrollTop = data.scrollTop;
this.mPageY = e.changedTouches[0].pageY;
if (this.scrollTop <= 0) {
let translateY = ((this.mPageY - this.sPageY) / 2) + this.pointY;
this.translateY = (translateY < 0 ? 0 : translateY);
if(this.pullDownStatus != 3) {
if(this.translateY < this.pullDownDistance) {
this.pullDownStatus = 1;
} else if(this.translateY >= this.pullDownDistance) {
this.pullDownStatus = 2;
}
}
}
}).exec();
},
endFn(e) {
this.isDown = false;
this.ePageY = e.changedTouches[0].pageY;
setTimeout(() => {
this.translateY = this.translateY >= this.pullDownDistance ? this.pullDownDistance : 0;
if(this.pullDownStatus == 2) { // 开始刷新
this.pullDownStatus = 3;
this.$emit('onPullDown',this.endPullDown);
}
},100)
},
endPullDown(mm) {
if(this.timeout) clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.translateY = 0;
this.pullDownStatus = 1;
}, mm || 0);
},
prevent(e) {
if(this.translateY > 0) {
e.preventDefault();
}
},
scroll(e) {
this.$emit('onScroll',e);
this.oldTop = e.detail.scrollTop;
if(this.timeout) clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.scrolltolower(e);
},20);
},
scrolltolower(e) {
let view = uni.createSelectorQuery().in(this).select(".you-scroll-inner");
view.fields({
size: true,
scrollOffset: true
}, data => {
if(data.scrollTop >= (e.detail.scrollHeight - data.height - this.reachBottomDistance)) {
this.$emit('onLoadMore',e);
}
}).exec();
},
isWeixinCient(){
var ua = navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i)=="micromessenger") {
return true;
} else {
return false;
}
},
goTop(top) {
this.scrollToTop = this.oldTop;
this.$nextTick(function() {
this.scrollToTop = top || 0;
});
}
},
mounted() {
// #ifdef H5
if(this.isWeixinCient()) {
document.body.addEventListener('touchmove', this.prevent);
}
// #endif
},
destroyed() {
// #ifdef H5
if(this.isWeixinCient()) {
document.body.removeEventListener('touchmove', this.prevent);
}
// #endif
}
}
</script>
<style scoped>
.you-scroll {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
// background-color: #eee;
}
.you-scroll .pullDown {
width: 100%;
height: 40px;
line-height: 50px;
text-align: center;
font-size: 14px;
overflow: hidden;
transform: translateY(-100%);
position: absolute;
top: -40px;
left: 0;
}
.you-scroll .pullDown .down-icon {
width: 40px;
height: 32px;
display: inline-block;
vertical-align: middle;
}
.you-scroll .pullDown .animate {
-webkit-animation: scaleIcon 1s infinite linear;
-moz-animation: scaleIcon 1s infinite linear;
-ms-animation: scaleIcon 1s infinite linear;
animation: scaleIcon 1s infinite linear;
}
.you-scroll .pullDown span {
white-space: nowrap;
overflow: hidden;
display: inline-block;
vertical-align: middle;
}
.you-scroll .you-scroll-inner {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
}
.you-scroll-content {
overflow: hidden;
}
@-webkit-keyframes scaleIcon {
0% {
transform: scaleY(1);
}
40% {
transform: scaleY(0.8);
}
80% {
transform: scaleY(0.9);
}
100% {
transform: scaleY(1);
}
}
@-moz-keyframes scaleIcon {
0% {
transform: scaleY(1);
}
40% {
transform: scaleY(0.8);
}
80% {
transform: scaleY(0.9);
}
100% {
transform: scaleY(1);
}
}
@-ms-keyframes scaleIcon {
0% {
transform: scaleY(1);
}
40% {
transform: scaleY(0.8);
}
80% {
transform: scaleY(0.9);
}
100% {
transform: scaleY(1);
}
}
@keyframes scaleIcon {
0% {
transform: scaleY(1);
}
40% {
transform: scaleY(0.8);
}
80% {
transform: scaleY(0.9);
}
100% {
transform: scaleY(1);
}
}
</style>