This commit is contained in:
2025-05-13 16:56:30 +08:00
838 changed files with 923 additions and 88523 deletions

View File

@ -1,4 +0,0 @@
{
"component": true,
"usingComponents": {}
}

View File

@ -1 +0,0 @@
<view class="{{['mescroll-empty',(option.fixed)?'empty-fixed':'']}}" style="{{'z-index:'+(option.zIndex)+';'+('top:'+(option.top)+';')}}"><view><block wx:if="{{icon}}"><image class="empty-icon" src="{{icon}}" mode="widthFix"></image></block></view><block wx:if="{{tip}}"><view class="empty-tip">{{tip}}</view></block><block wx:if="{{option.btnText}}"><view data-event-opts="{{[['tap',[['emptyClick',['$event']]]]]}}" class="empty-btn" bindtap="__e">{{option.btnText}}</view></block></view>

View File

@ -1,85 +0,0 @@
/* 无任何数据的空布局 */
.mescroll-empty {
box-sizing: border-box;
width: 100%;
padding: 100rpx 50rpx;
text-align: center;
}
.mescroll-empty.empty-fixed {
z-index: 99;
position: absolute; /*transform会使fixed失效,最终会降级为absolute */
top: 100rpx;
left: 0;
}
.mescroll-empty .empty-icon {
width: 280rpx;
height: 280rpx;
}
.mescroll-empty .empty-tip {
margin-top: 20rpx;
font-size: 24rpx;
color: gray;
}
.mescroll-empty .empty-btn {
display: inline-block;
margin-top: 40rpx;
min-width: 200rpx;
padding: 18rpx;
font-size: 28rpx;
border: 1rpx solid #e04b28;
border-radius: 60rpx;
color: #e04b28;
}
.mescroll-empty .empty-btn:active {
opacity: 0.75;
}

View File

@ -1,4 +0,0 @@
{
"component": true,
"usingComponents": {}
}

View File

@ -1 +0,0 @@
<block wx:if="{{mOption.src}}"><image class="{{['mescroll-totop',value?'mescroll-totop-in':'mescroll-totop-out',[(mOption.safearea)?'mescroll-totop-safearea':'']]}}" style="{{'z-index:'+(mOption.zIndex)+';'+('left:'+(left)+';')+('right:'+(right)+';')+('bottom:'+($root.m0)+';')+('width:'+($root.m1)+';')+('border-radius:'+($root.m2)+';')}}" src="{{mOption.src}}" mode="widthFix" data-event-opts="{{[['tap',[['toTopClick',['$event']]]]]}}" bindtap="__e"></image></block>

View File

@ -1,80 +0,0 @@
/* 回到顶部的按钮 */
.mescroll-totop {
z-index: 9990;
position: fixed !important; /* 加上important避免编译到H5,在多mescroll中定位失效 */
right: 20rpx;
bottom: 120rpx;
width: 72rpx;
height: auto;
border-radius: 50%;
opacity: 0;
transition: opacity 0.5s; /* 过渡 */
margin-bottom: 0px; /* css变量 */
}
/* 适配 iPhoneX */
@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
.mescroll-totop-safearea {
margin-bottom: calc(0px + constant(safe-area-inset-bottom)); /* window-bottom + 适配 iPhoneX */
margin-bottom: calc(0px + env(safe-area-inset-bottom));
}
}
/* 显示 -- 淡入 */
.mescroll-totop-in {
opacity: 1;
}
/* 隐藏 -- 淡出且不接收事件*/
.mescroll-totop-out {
opacity: 0;
pointer-events: none;
}

View File

@ -1,7 +0,0 @@
{
"usingComponents": {
"mescroll-empty": "/components/mescroll-uni/components/mescroll-empty",
"mescroll-top": "/components/mescroll-uni/components/mescroll-top"
},
"component": true
}

View File

@ -1,2 +0,0 @@
<wxs src="./wxs/wxs.wxs" module="wxsBiz"></wxs>
<view class="{{['mescroll-body','mescroll-render-touch',(sticky)?'mescorll-sticky':'']}}" style="{{'min-height:'+(minHeight)+';'+('padding-top:'+(padTop)+';')+('padding-bottom:'+(padBottom)+';')}}" change:prop="{{wxsBiz.propObserver}}" prop="{{wxsProp}}" bindtouchstart="{{wxsBiz.touchstartEvent}}" bindtouchmove="{{wxsBiz.touchmoveEvent}}" bindtouchend="{{wxsBiz.touchendEvent}}" bindtouchcancel="{{wxsBiz.touchendEvent}}"><block wx:if="{{topbar&&statusBarHeight}}"><view class="mescroll-topbar" style="{{'height:'+(statusBarHeight+'px')+';'+('background:'+(topbar)+';')}}"></view></block><view class="mescroll-body-content mescroll-wxs-content" style="{{'transform:'+(translateY)+';'+('transition:'+(transition)+';')}}" change:prop="{{wxsBiz.callObserver}}" prop="{{callProp}}"><block wx:if="{{mescroll.optDown.use}}"><view class="mescroll-downwarp" style="{{'background:'+(mescroll.optDown.bgColor)+';'+('color:'+(mescroll.optDown.textColor)+';')}}"><view class="downwarp-content"><view class="{{['downwarp-progress','mescroll-wxs-progress',(isDownLoading)?'mescroll-rotate':'']}}" style="{{'border-color:'+(mescroll.optDown.textColor)+';'+('transform:'+(downRotate)+';')}}"></view><view class="downwarp-tip">{{downText}}</view></view></view></block><slot></slot><block wx:if="{{isShowEmpty}}"><mescroll-empty vue-id="440ed908-1" option="{{mescroll.optUp.empty}}" data-event-opts="{{[['^emptyclick',[['emptyClick']]]]}}" bind:emptyclick="__e" bind:__l="__l"></mescroll-empty></block><block wx:if="{{mescroll.optUp.use&&!isDownLoading&&upLoadType!==3}}"><view class="mescroll-upwarp" style="{{'background:'+(mescroll.optUp.bgColor)+';'+('color:'+(mescroll.optUp.textColor)+';')}}"><view hidden="{{!(upLoadType===1)}}"><view class="upwarp-progress mescroll-rotate" style="{{'border-color:'+(mescroll.optUp.textColor)+';'}}"></view><view class="upwarp-tip">{{mescroll.optUp.textLoading}}</view></view><block wx:if="{{upLoadType===2}}"><view class="upwarp-nodata">{{mescroll.optUp.textNoMore}}</view></block></view></block></view><block wx:if="{{safearea}}"><view class="mescroll-safearea"></view></block><mescroll-top vue-id="440ed908-2" option="{{mescroll.optUp.toTop}}" value="{{isShowToTop}}" data-event-opts="{{[['^click',[['toTopClick']]],['^input',[['__set_model',['','isShowToTop','$event',[]]]]]]}}" bind:click="__e" bind:input="__e" bind:__l="__l"></mescroll-top><view change:prop="{{renderBiz.propObserver}}" prop="{{wxsProp}}"></view></view>

View File

@ -1,145 +0,0 @@
.mescroll-body {
position: relative; /* 下拉刷新区域相对自身定位 */
height: auto; /* 不可固定高度,否则overflow:hidden导致无法滑动; 同时使设置的最小高生效,实现列表不满屏仍可下拉*/
overflow: hidden; /* 当有元素写在mescroll-body标签前面时,可遮住下拉刷新区域 */
box-sizing: border-box; /* 避免设置padding出现双滚动条的问题 */
}
/* 使sticky生效: 父元素不能overflow:hidden或者overflow:auto属性 */
.mescroll-body.mescorll-sticky{
overflow: unset !important
}
/* 适配 iPhoneX */
@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
.mescroll-safearea {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
}
/* 下拉刷新区域 */
.mescroll-downwarp {
position: absolute;
top: -100%;
left: 0;
width: 100%;
height: 100%;
text-align: center;
}
/* 下拉刷新--内容区,定位于区域底部 */
.mescroll-downwarp .downwarp-content {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
min-height: 60rpx;
padding: 20rpx 0;
text-align: center;
}
/* 下拉刷新--提示文本 */
.mescroll-downwarp .downwarp-tip {
display: inline-block;
font-size: 28rpx;
vertical-align: middle;
margin-left: 16rpx;
/* color: gray; 已在style设置color,此处删去*/
}
/* 下拉刷新--旋转进度条 */
.mescroll-downwarp .downwarp-progress {
display: inline-block;
width: 32rpx;
height: 32rpx;
border-radius: 50%;
border: 2rpx solid gray;
border-bottom-color: transparent !important; /*已在style设置border-color,此处需加 !important*/
vertical-align: middle;
}
/* 旋转动画 */
.mescroll-downwarp .mescroll-rotate {
-webkit-animation: mescrollDownRotate 0.6s linear infinite;
animation: mescrollDownRotate 0.6s linear infinite;
}
@-webkit-keyframes mescrollDownRotate {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes mescrollDownRotate {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
/* 上拉加载区域 */
.mescroll-upwarp {
box-sizing: border-box;
min-height: 110rpx;
padding: 30rpx 0;
text-align: center;
clear: both;
}
/*提示文本 */
.mescroll-upwarp .upwarp-tip,
.mescroll-upwarp .upwarp-nodata {
display: inline-block;
font-size: 28rpx;
vertical-align: middle;
/* color: gray; 已在style设置color,此处删去*/
}
.mescroll-upwarp .upwarp-tip {
margin-left: 16rpx;
}
/*旋转进度条 */
.mescroll-upwarp .upwarp-progress {
display: inline-block;
width: 32rpx;
height: 32rpx;
border-radius: 50%;
border: 2rpx solid gray;
border-bottom-color: transparent !important; /*已在style设置border-color,此处需加 !important*/
vertical-align: middle;
}
/* 旋转动画 */
.mescroll-upwarp .mescroll-rotate {
-webkit-animation: mescrollUpRotate 0.6s linear infinite;
animation: mescrollUpRotate 0.6s linear infinite;
}
@-webkit-keyframes mescrollUpRotate {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes mescrollUpRotate {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}

View File

@ -1,7 +0,0 @@
{
"usingComponents": {
"mescroll-empty": "/components/mescroll-uni/components/mescroll-empty",
"mescroll-top": "/components/mescroll-uni/components/mescroll-top"
},
"component": true
}

View File

@ -1,2 +0,0 @@
<wxs src="./wxs/wxs.wxs" module="wxsBiz"></wxs>
<view class="mescroll-uni-warp"><scroll-view class="{{['mescroll-uni',(isFixed)?'mescroll-uni-fixed':'']}}" style="{{'height:'+(scrollHeight)+';'+('padding-top:'+(padTop)+';')+('padding-bottom:'+(padBottom)+';')+('top:'+(fixedTop)+';')+('bottom:'+(fixedBottom)+';')}}" id="{{viewId}}" scroll-top="{{scrollTop}}" scroll-with-animation="{{scrollAnim}}" scroll-y="{{scrollable}}" enable-back-to-top="{{true}}" throttle="{{false}}" data-event-opts="{{[['scroll',[['scroll',['$event']]]]]}}" bindscroll="__e"><view class="mescroll-uni-content mescroll-render-touch" change:prop="{{wxsBiz.propObserver}}" prop="{{wxsProp}}" bindtouchstart="{{wxsBiz.touchstartEvent}}" bindtouchmove="{{wxsBiz.touchmoveEvent}}" bindtouchend="{{wxsBiz.touchendEvent}}" bindtouchcancel="{{wxsBiz.touchendEvent}}"><block wx:if="{{topbar&&statusBarHeight}}"><view class="mescroll-topbar" style="{{'height:'+(statusBarHeight+'px')+';'+('background:'+(topbar)+';')}}"></view></block><view class="mescroll-wxs-content" style="{{'transform:'+(translateY)+';'+('transition:'+(transition)+';')}}" change:prop="{{wxsBiz.callObserver}}" prop="{{callProp}}"><block wx:if="{{mescroll.optDown.use}}"><view class="mescroll-downwarp" style="{{'background:'+(mescroll.optDown.bgColor)+';'+('color:'+(mescroll.optDown.textColor)+';')}}"><view class="downwarp-content"><view class="{{['downwarp-progress','mescroll-wxs-progress',(isDownLoading)?'mescroll-rotate':'']}}" style="{{'border-color:'+(mescroll.optDown.textColor)+';'+('transform:'+(downRotate)+';')}}"></view><view class="downwarp-tip">{{downText}}</view></view></view></block><slot></slot><block wx:if="{{isShowEmpty}}"><mescroll-empty vue-id="55fe4702-1" option="{{mescroll.optUp.empty}}" data-event-opts="{{[['^emptyclick',[['emptyClick']]]]}}" bind:emptyclick="__e" bind:__l="__l"></mescroll-empty></block><block wx:if="{{mescroll.optUp.use&&!isDownLoading&&upLoadType!==3}}"><view class="mescroll-upwarp" style="{{'background:'+(mescroll.optUp.bgColor)+';'+('color:'+(mescroll.optUp.textColor)+';')}}"><view hidden="{{!(upLoadType===1)}}"><view class="upwarp-progress mescroll-rotate" style="{{'border-color:'+(mescroll.optUp.textColor)+';'}}"></view><view class="upwarp-tip">{{mescroll.optUp.textLoading}}</view></view><block wx:if="{{upLoadType===2}}"><view class="upwarp-nodata">{{mescroll.optUp.textNoMore}}</view></block></view></block></view><block wx:if="{{safearea}}"><view class="mescroll-safearea"></view></block></view></scroll-view><mescroll-top vue-id="55fe4702-2" option="{{mescroll.optUp.toTop}}" value="{{isShowToTop}}" data-event-opts="{{[['^click',[['toTopClick']]],['^input',[['__set_model',['','isShowToTop','$event',[]]]]]]}}" bind:click="__e" bind:input="__e" bind:__l="__l"></mescroll-top><view change:prop="{{renderBiz.propObserver}}" prop="{{wxsProp}}"></view></view>

View File

@ -1,160 +0,0 @@
.mescroll-uni-warp{
height: 100%;
}
.mescroll-uni-content{
height: 100%;
}
.mescroll-uni {
position: relative;
width: 100%;
height: 100%;
min-height: 200rpx;
overflow-y: auto;
box-sizing: border-box; /* 避免设置padding出现双滚动条的问题 */
}
/* 定位的方式固定高度 */
.mescroll-uni-fixed{
z-index: 1;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: auto; /* 使right生效 */
height: auto; /* 使bottom生效 */
}
/* 适配 iPhoneX */
@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
.mescroll-safearea {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
}
/* 下拉刷新区域 */
.mescroll-downwarp {
position: absolute;
top: -100%;
left: 0;
width: 100%;
height: 100%;
text-align: center;
}
/* 下拉刷新--内容区,定位于区域底部 */
.mescroll-downwarp .downwarp-content {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
min-height: 60rpx;
padding: 20rpx 0;
text-align: center;
}
/* 下拉刷新--提示文本 */
.mescroll-downwarp .downwarp-tip {
display: inline-block;
font-size: 28rpx;
vertical-align: middle;
margin-left: 16rpx;
/* color: gray; 已在style设置color,此处删去*/
}
/* 下拉刷新--旋转进度条 */
.mescroll-downwarp .downwarp-progress {
display: inline-block;
width: 32rpx;
height: 32rpx;
border-radius: 50%;
border: 2rpx solid gray;
border-bottom-color: transparent !important; /*已在style设置border-color,此处需加 !important*/
vertical-align: middle;
}
/* 旋转动画 */
.mescroll-downwarp .mescroll-rotate {
-webkit-animation: mescrollDownRotate 0.6s linear infinite;
animation: mescrollDownRotate 0.6s linear infinite;
}
@-webkit-keyframes mescrollDownRotate {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes mescrollDownRotate {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
/* 上拉加载区域 */
.mescroll-upwarp {
box-sizing: border-box;
min-height: 110rpx;
padding: 30rpx 0;
text-align: center;
clear: both;
}
/*提示文本 */
.mescroll-upwarp .upwarp-tip,
.mescroll-upwarp .upwarp-nodata {
display: inline-block;
font-size: 28rpx;
vertical-align: middle;
/* color: gray; 已在style设置color,此处删去*/
}
.mescroll-upwarp .upwarp-tip {
margin-left: 16rpx;
}
/*旋转进度条 */
.mescroll-upwarp .upwarp-progress {
display: inline-block;
width: 32rpx;
height: 32rpx;
border-radius: 50%;
border: 2rpx solid gray;
border-bottom-color: transparent !important; /*已在style设置border-color,此处需加 !important*/
vertical-align: middle;
}
/* 旋转动画 */
.mescroll-upwarp .mescroll-rotate {
-webkit-animation: mescrollUpRotate 0.6s linear infinite;
animation: mescrollUpRotate 0.6s linear infinite;
}
@-webkit-keyframes mescrollUpRotate {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes mescrollUpRotate {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}

View File

@ -1,271 +0,0 @@
// 使用wxs处理交互动画, 提高性能, 同时避免小程序bounce对下拉刷新的影响
// https://uniapp.dcloud.io/frame?id=wxs
// https://developers.weixin.qq.com/miniprogram/dev/framework/view/interactive-animation.html
// 模拟mescroll实例, 与mescroll.js的写法尽量保持一致
var me = {}
// ------ 自定义下拉刷新动画 start ------
/* 下拉过程中的回调,滑动过程一直在执行 (rate<1为inOffset; rate>1为outOffset) */
me.onMoving = function (ins, rate, downHight){
ins.requestAnimationFrame(function () {
ins.selectComponent('.mescroll-wxs-content').setStyle({
'will-change': 'transform', // 可解决下拉过程中, image和swiper脱离文档流的问题
'transform': 'translateY(' + downHight + 'px)',
'transition': ''
})
// 环形进度条
var progress = ins.selectComponent('.mescroll-wxs-progress')
progress && progress.setStyle({transform: 'rotate(' + 360 * rate + 'deg)'})
})
}
/* 显示下拉刷新进度 */
me.showLoading = function (ins){
me.downHight = me.optDown.offset
ins.requestAnimationFrame(function () {
ins.selectComponent('.mescroll-wxs-content').setStyle({
'will-change': 'auto',
'transform': 'translateY(' + me.downHight + 'px)',
'transition': 'transform 300ms'
})
})
}
/* 结束下拉 */
me.endDownScroll = function (ins){
me.downHight = 0;
me.isDownScrolling = false;
ins.requestAnimationFrame(function () {
ins.selectComponent('.mescroll-wxs-content').setStyle({
'will-change': 'auto',
'transform': 'translateY(0)', // 不可以写空串,否则scroll-view渲染不完整 (延时350ms会调clearTransform置空)
'transition': 'transform 300ms'
})
})
}
/* 结束下拉动画执行完毕后, 清除transform和transition, 避免对列表内容样式造成影响, 如: h5的list-msg示例下拉进度条漏出来等 */
me.clearTransform = function (ins){
ins.requestAnimationFrame(function () {
ins.selectComponent('.mescroll-wxs-content').setStyle({
'will-change': '',
'transform': '',
'transition': ''
})
})
}
// ------ 自定义下拉刷新动画 end ------
/**
* 监听逻辑层数据的变化 (实时更新数据)
*/
function propObserver(wxsProp) {
if (wxsProp) {
me.optDown = wxsProp.optDown
me.scrollTop = wxsProp.scrollTop
me.bodyHeight = wxsProp.bodyHeight
me.isDownScrolling = wxsProp.isDownScrolling
me.isUpScrolling = wxsProp.isUpScrolling
me.isUpBoth = wxsProp.isUpBoth
me.isScrollBody = wxsProp.isScrollBody
me.startTop = wxsProp.scrollTop // 及时更新touchstart触发的startTop, 避免scroll-view快速惯性滚动到顶部取值不准确
}
}
/**
* 监听逻辑层数据的变化 (调用wxs的方法)
*/
function callObserver(callProp, oldValue, ins) {
if(!callProp) return;
if (me.disabled()) return;
if(callProp.callType){
// 逻辑层App Service的style已失效,需在视图层Webview设置style
if(callProp.callType === 'showLoading'){
me.showLoading(ins)
}else if(callProp.callType === 'endDownScroll'){
me.endDownScroll(ins)
}else if(callProp.callType === 'clearTransform'){
me.clearTransform(ins)
}
}
}
/**
* touch事件
*/
function touchstartEvent(e, ins) {
me.downHight = 0; // 下拉的距离
me.startPoint = me.getPoint(e); // 记录起点
me.startTop = me.getScrollTop(); // 记录此时的滚动条位置
me.startAngle = 0; // 初始角度
me.lastPoint = me.startPoint; // 重置上次move的点
me.maxTouchmoveY = me.getBodyHeight() - me.optDown.bottomOffset; // 手指触摸的最大范围(写在touchstart避免body获取高度为0的情况)
me.inTouchend = false; // 标记不是touchend
me.callMethod(ins, {type: 'setWxsProp'}) // 同步更新wxsProp的数据 (小程序是异步的,可能touchmove先执行,才到propObserver; h5和app是同步)
}
function touchmoveEvent(e, ins) {
var isPrevent = true // false表示不往上冒泡相当于调用了同时调用了stopPropagation和preventDefault (对小程序生效, h5和app无效)
if (me.disabled()) return isPrevent;
var scrollTop = me.getScrollTop(); // 当前滚动条的距离
var curPoint = me.getPoint(e); // 当前点
var moveY = curPoint.y - me.startPoint.y; // 和起点比,移动的距离,大于0向下拉,小于0向上拉
// 向下拉 && 在顶部
// mescroll-body,直接判定在顶部即可
// scroll-view在滚动时不会触发touchmove,当触顶/底/左/右时,才会触发touchmove
// scroll-view滚动到顶部时,scrollTop不一定为0,也有可能大于0; 在iOS的APP中scrollTop可能为负数,不一定和startTop相等
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.isUpBoth))) {
// 下拉的角度是否在配置的范围内
if(!me.startAngle) me.startAngle = me.getAngle(me.lastPoint, curPoint); // 两点之间的角度,区间 [0,90]
if (me.startAngle < me.optDown.minAngle) return isPrevent; // 如果小于配置的角度,则不往下执行下拉刷新
// 如果手指的位置超过配置的距离,则提前结束下拉,避免Webview嵌套导致touchend无法触发
if (me.maxTouchmoveY > 0 && curPoint.y >= me.maxTouchmoveY) {
me.inTouchend = true; // 标记执行touchend
touchendEvent(e, ins); // 提前触发touchend
return isPrevent;
}
isPrevent = false // 小程序是return false
var diff = curPoint.y - me.lastPoint.y; // 和上次比,移动的距离 (大于0向下,小于0向上)
// 下拉距离 < 指定距离
if (me.downHight < me.optDown.offset) {
if (me.movetype !== 1) {
me.movetype = 1; // 加入标记,保证只执行一次
// me.optDown.inOffset && me.optDown.inOffset(me); // 进入指定距离范围内那一刻的回调,只执行一次
me.callMethod(ins, {type: 'setLoadType', downLoadType: 1})
me.isMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来
}
me.downHight += diff * me.optDown.inOffsetRate; // 越往下,高度变化越小
// 指定距离 <= 下拉距离
} else {
if (me.movetype !== 2) {
me.movetype = 2; // 加入标记,保证只执行一次
// me.optDown.outOffset && me.optDown.outOffset(me); // 下拉超过指定距离那一刻的回调,只执行一次
me.callMethod(ins, {type: 'setLoadType', downLoadType: 2})
me.isMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来
}
if (diff > 0) { // 向下拉
me.downHight += diff * me.optDown.outOffsetRate; // 越往下,高度变化越小
} else { // 向上收
me.downHight += diff; // 向上收回高度,则向上滑多少收多少高度
}
}
me.downHight = Math.round(me.downHight) // 取整
var rate = me.downHight / me.optDown.offset; // 下拉区域当前高度与指定距离的比值
// me.optDown.onMoving && me.optDown.onMoving(me, rate, me.downHight); // 下拉过程中的回调,一直在执行
me.onMoving(ins, rate, me.downHight)
}
}
me.lastPoint = curPoint; // 记录本次移动的点
return isPrevent // false表示不往上冒泡相当于调用了同时调用了stopPropagation和preventDefault (对小程序生效, h5和app无效)
}
function touchendEvent(e, ins) {
// 如果下拉区域高度已改变,则需重置回来
if (me.isMoveDown) {
if (me.downHight >= me.optDown.offset) {
// 符合触发刷新的条件
me.downHight = me.optDown.offset; // 更新下拉区域高度
// me.triggerDownScroll();
me.callMethod(ins, {type: 'triggerDownScroll'})
} else {
// 不符合的话 则重置
me.downHight = 0;
// me.optDown.endDownScroll && me.optDown.endDownScroll(me);
me.callMethod(ins, {type: 'endDownScroll'})
}
me.movetype = 0;
me.isMoveDown = false;
} else if (!me.isScrollBody && me.getScrollTop() === me.startTop) { // scroll-view到顶/左/右/底的滑动事件
var isScrollUp = me.getPoint(e).y - me.startPoint.y < 0; // 和起点比,移动的距离,大于0向下拉,小于0向上拉
// 上滑
if (isScrollUp) {
// 需检查滑动的角度
var angle = me.getAngle(me.getPoint(e), me.startPoint); // 两点之间的角度,区间 [0,90]
if (angle > 80) {
// 检查并触发上拉
// me.triggerUpScroll(true);
me.callMethod(ins, {type: 'triggerUpScroll'})
}
}
}
me.callMethod(ins, {type: 'setWxsProp'}) // 同步更新wxsProp的数据 (小程序是异步的,可能touchmove先执行,才到propObserver; h5和app是同步)
}
/* 是否禁用下拉刷新 */
me.disabled = function(){
return !me.optDown || !me.optDown.use || me.optDown.native
}
/* 根据点击滑动事件获取第一个手指的坐标 */
me.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}
}
}
/* 计算两点之间的角度: 区间 [0,90]*/
me.getAngle = function (p1, p2) {
var x = Math.abs(p1.x - p2.x);
var y = Math.abs(p1.y - p2.y);
var z = Math.sqrt(x * x + y * y);
var angle = 0;
if (z !== 0) {
angle = Math.asin(y / z) / Math.PI * 180;
}
return angle
}
/* 获取滚动条的位置 */
me.getScrollTop = function() {
return me.scrollTop || 0
}
/* 获取body的高度 */
me.getBodyHeight = function() {
return me.bodyHeight || 0;
}
/* 调用逻辑层的方法 */
me.callMethod = function(ins, param) {
if(ins) ins.callMethod('wxsCall', param)
}
/* 导出模块 */
module.exports = {
propObserver: propObserver,
callObserver: callObserver,
touchstartEvent: touchstartEvent,
touchmoveEvent: touchmoveEvent,
touchendEvent: touchendEvent
}