This commit is contained in:
2026-04-14 17:38:46 +08:00
commit b71e6d6bae
2848 changed files with 237896 additions and 0 deletions

View File

@ -0,0 +1,10 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["components/mescroll-uni/components/mescroll-empty"],{2253:function(t,n,e){"use strict";var i=e("47a9");Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var o=i(e("f235")),u={props:{option:{type:Object,default:function(){return{}}}},computed:{icon:function(){return null==this.option.icon?o.default.up.empty.icon:this.option.icon},tip:function(){return null==this.option.tip?o.default.up.empty.tip:this.option.tip}},methods:{emptyClick:function(){this.$emit("emptyclick")}}};n.default=u},"30c2":function(t,n,e){"use strict";var i=e("8924"),o=e.n(i);o.a},6827:function(t,n,e){"use strict";e.r(n);var i=e("bc32"),o=e("ae47");for(var u in o)["default"].indexOf(u)<0&&function(t){e.d(n,t,(function(){return o[t]}))}(u);e("30c2");var c=e("828b"),r=Object(c["a"])(o["default"],i["b"],i["c"],!1,null,null,null,!1,i["a"],void 0);n["default"]=r.exports},8924:function(t,n,e){},ae47:function(t,n,e){"use strict";e.r(n);var i=e("2253"),o=e.n(i);for(var u in i)["default"].indexOf(u)<0&&function(t){e.d(n,t,(function(){return i[t]}))}(u);n["default"]=o.a},bc32:function(t,n,e){"use strict";e.d(n,"b",(function(){return i})),e.d(n,"c",(function(){return o})),e.d(n,"a",(function(){}));var i=function(){var t=this.$createElement;this._self._c},o=[]}}]);
;(global["webpackJsonp"] = global["webpackJsonp"] || []).push([
'components/mescroll-uni/components/mescroll-empty-create-component',
{
'components/mescroll-uni/components/mescroll-empty-create-component':(function(module, exports, __webpack_require__){
__webpack_require__('df3c')['createComponent'](__webpack_require__("6827"))
})
},
[['components/mescroll-uni/components/mescroll-empty-create-component']]
]);

View File

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

View File

@ -0,0 +1 @@
<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

@ -0,0 +1 @@
.mescroll-empty{box-sizing:border-box;width:100%;padding:200rpx 50rpx;text-align:center}.mescroll-empty.empty-fixed{z-index:99;position:absolute;top:100rpx;left:0}.mescroll-empty .empty-icon{width:300rpx;height:300rpx}.mescroll-empty .empty-tip{margin-top:20rpx;font-size:26rpx;color:grey}.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:.75}

View File

@ -0,0 +1,10 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["components/mescroll-uni/components/mescroll-top"],{"31c5":function(t,n,i){"use strict";i.r(n);var o=i("d1e5"),e=i("3fc9");for(var u in e)["default"].indexOf(u)<0&&function(t){i.d(n,t,(function(){return e[t]}))}(u);i("c86d");var c=i("828b"),r=Object(c["a"])(e["default"],o["b"],o["c"],!1,null,null,null,!1,o["a"],void 0);n["default"]=r.exports},"3fc9":function(t,n,i){"use strict";i.r(n);var o=i("6143"),e=i.n(o);for(var u in o)["default"].indexOf(u)<0&&function(t){i.d(n,t,(function(){return o[t]}))}(u);n["default"]=e.a},6143:function(t,n,i){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var o={props:{option:Object,value:!1},computed:{mOption:function(){return this.option||{}},left:function(){return this.mOption.left?this.addUnit(this.mOption.left):"auto"},right:function(){return this.mOption.left?"auto":this.addUnit(this.mOption.right)}},methods:{addUnit:function(t){return t?"number"===typeof t?t+"rpx":t:0},toTopClick:function(){this.$emit("input",!1),this.$emit("click")}}};n.default=o},c86d:function(t,n,i){"use strict";var o=i("f460"),e=i.n(o);e.a},d1e5:function(t,n,i){"use strict";i.d(n,"b",(function(){return o})),i.d(n,"c",(function(){return e})),i.d(n,"a",(function(){}));var o=function(){var t=this,n=t.$createElement,i=(t._self._c,t.mOption.src?t.addUnit(t.mOption.bottom):null),o=t.mOption.src?t.addUnit(t.mOption.width):null,e=t.mOption.src?t.addUnit(t.mOption.radius):null;t.$mp.data=Object.assign({},{$root:{m0:i,m1:o,m2:e}})},e=[]},f460:function(t,n,i){}}]);
;(global["webpackJsonp"] = global["webpackJsonp"] || []).push([
'components/mescroll-uni/components/mescroll-top-create-component',
{
'components/mescroll-uni/components/mescroll-top-create-component':(function(module, exports, __webpack_require__){
__webpack_require__('df3c')['createComponent'](__webpack_require__("31c5"))
})
},
[['components/mescroll-uni/components/mescroll-top-create-component']]
]);

View File

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

View File

@ -0,0 +1 @@
<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

@ -0,0 +1 @@
.mescroll-totop{z-index:9990;position:fixed!important;right:20rpx;bottom:120rpx;width:84rpx;height:auto;border-radius:50%;opacity:0;transition:opacity .5s;margin-bottom:0}@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));margin-bottom:calc(0px + env(safe-area-inset-bottom))}}.mescroll-totop-in{opacity:1}.mescroll-totop-out{opacity:0;pointer-events:none}

File diff suppressed because one or more lines are too long

View File

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

View File

@ -0,0 +1,2 @@
<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

@ -0,0 +1,2 @@
.mescroll-body{position:relative;height:auto;overflow:hidden;box-sizing:border-box}.mescroll-body .downwarp-content{display:flex;justify-content:center;align-items:center}.mescroll-body.mescorll-sticky{overflow:unset!important}@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}.mescroll-downwarp .downwarp-progress{display:inline-block;width:32rpx;height:32rpx;border-radius:50%;border:2rpx solid grey;border-bottom-color:transparent!important;vertical-align:middle}.mescroll-downwarp .mescroll-rotate{-webkit-animation:mescrollDownRotate .6s linear infinite;animation:mescrollDownRotate .6s linear infinite}@-webkit-keyframes mescrollDownRotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes mescrollDownRotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.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}.mescroll-upwarp .upwarp-tip{margin-left:16rpx}.mescroll-upwarp .upwarp-progress{display:inline-block;width:32rpx;height:32rpx;border-radius:50%;border:2rpx solid grey;border-bottom-color:transparent!important;vertical-align:middle}.mescroll-upwarp .mescroll-rotate{-webkit-animation:mescrollUpRotate .6s linear infinite;animation:mescrollUpRotate .6s linear infinite}@-webkit-keyframes mescrollUpRotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes mescrollUpRotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}

File diff suppressed because one or more lines are too long

View File

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

View File

@ -0,0 +1,2 @@
<wxs src="./wxs/wxs.wxs" module="wxsBiz"></wxs>
<view class="mescroll-uni-warp data-v-041279ba"><scroll-view class="{{['mescroll-uni','data-v-041279ba',(isFixed)?'mescroll-uni-fixed':'']}}" style="{{'height:'+(scrollHeight)+';'+('padding-top:'+(padTop)+';')+('padding-bottom:'+(padBottom)+';')+('top:'+(fixedTop)+';')+('bottom:'+(fixedBottom)+';')+('background-color:'+(bgColor)+';')}}" 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 data-v-041279ba" 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 data-v-041279ba" style="{{'height:'+(statusBarHeight+'px')+';'+('background:'+(topbar)+';')}}"></view></block><view class="mescroll-wxs-content data-v-041279ba" style="{{'transform:'+(translateY)+';'+('transition:'+(transition)+';')}}" change:prop="{{wxsBiz.callObserver}}" prop="{{callProp}}"><block wx:if="{{mescroll.optDown.use}}"><view class="mescroll-downwarp data-v-041279ba" style="{{'background:'+(mescroll.optDown.bgColor)+';'+('color:'+(mescroll.optDown.textColor)+';')}}"><view class="downwarp-content data-v-041279ba"><view class="{{['downwarp-progress','mescroll-wxs-progress','data-v-041279ba',(isDownLoading)?'mescroll-rotate':'']}}" style="{{'border-color:'+(mescroll.optDown.textColor)+';'+('transform:'+(downRotate)+';')}}"></view><view class="downwarp-tip data-v-041279ba">{{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" class="data-v-041279ba" bind:__l="__l"></mescroll-empty></block><block wx:if="{{mescroll.optUp.use&&!isDownLoading&&upLoadType!==3}}"><view class="mescroll-upwarp data-v-041279ba" style="{{'background:'+(mescroll.optUp.bgColor)+';'+('color:'+(mescroll.optUp.textColor)+';')}}"><view hidden="{{!(upLoadType===1)}}" class="data-v-041279ba"><view class="upwarp-progress mescroll-rotate data-v-041279ba" style="{{'border-color:'+(mescroll.optUp.textColor)+';'}}"></view><view class="upwarp-tip data-v-041279ba">{{mescroll.optUp.textLoading}}</view></view><block wx:if="{{upLoadType===2}}"><view class="upwarp-nodata data-v-041279ba">{{mescroll.optUp.textNoMore}}</view></block></view></block></view><block wx:if="{{safearea}}"><view class="mescroll-safearea data-v-041279ba"></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" class="data-v-041279ba" bind:__l="__l"></mescroll-top><view change:prop="{{renderBiz.propObserver}}" prop="{{wxsProp}}" class="data-v-041279ba"></view></view>

View File

@ -0,0 +1,2 @@
.mescroll-uni-warp.data-v-041279ba{height:100%}.mescroll-uni-content.data-v-041279ba{height:100%;position:relative}.mescroll-uni.data-v-041279ba{position:relative;width:100%;height:100%;min-height:200rpx;overflow-y:auto;box-sizing:border-box}.mescroll-uni-fixed.data-v-041279ba{z-index:1;position:fixed;top:0;left:0;right:0;bottom:0;width:auto;height:auto}@supports (bottom:constant(safe-area-inset-bottom)) or (bottom:env(safe-area-inset-bottom)){.mescroll-safearea.data-v-041279ba{padding-bottom:constant(safe-area-inset-bottom);padding-bottom:env(safe-area-inset-bottom)}}.mescroll-downwarp.data-v-041279ba{position:absolute;top:-100%;left:0;width:100%;height:100%;text-align:center}.mescroll-downwarp .downwarp-content.data-v-041279ba{position:absolute;left:0;bottom:0;width:100%;min-height:60rpx;padding:20rpx 0;text-align:center}.mescroll-downwarp .downwarp-tip.data-v-041279ba{display:inline-block;font-size:28rpx;vertical-align:middle;margin-left:16rpx}.mescroll-downwarp .downwarp-progress.data-v-041279ba{display:inline-block;width:32rpx;height:32rpx;border-radius:50%;border:2rpx solid grey;border-bottom-color:transparent!important;vertical-align:middle}.mescroll-downwarp .mescroll-rotate.data-v-041279ba{-webkit-animation:mescrollDownRotate-data-v-041279ba .6s linear infinite;animation:mescrollDownRotate-data-v-041279ba .6s linear infinite}@-webkit-keyframes mescrollDownRotate-data-v-041279ba{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes mescrollDownRotate-data-v-041279ba{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.mescroll-upwarp.data-v-041279ba{box-sizing:border-box;min-height:110rpx;padding:30rpx 0;text-align:center;clear:both}.mescroll-upwarp .upwarp-tip.data-v-041279ba,
.mescroll-upwarp .upwarp-nodata.data-v-041279ba{display:inline-block;font-size:28rpx;vertical-align:middle}.mescroll-upwarp .upwarp-tip.data-v-041279ba{margin-left:16rpx}.mescroll-upwarp .upwarp-progress.data-v-041279ba{display:inline-block;width:32rpx;height:32rpx;border-radius:50%;border:2rpx solid grey;border-bottom-color:transparent!important;vertical-align:middle}.mescroll-upwarp .mescroll-rotate.data-v-041279ba{-webkit-animation:mescrollUpRotate-data-v-041279ba .6s linear infinite;animation:mescrollUpRotate-data-v-041279ba .6s linear infinite}@-webkit-keyframes mescrollUpRotate-data-v-041279ba{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes mescrollUpRotate-data-v-041279ba{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}

View File

@ -0,0 +1,268 @@
// 使用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) {
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 (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
}