diff --git a/components/amount/DINPro-Medium.ttf b/components/amount/DINPro-Medium.ttf deleted file mode 100644 index 2607a13..0000000 Binary files a/components/amount/DINPro-Medium.ttf and /dev/null differ diff --git a/components/amount/_util/animate.js b/components/amount/_util/animate.js deleted file mode 100644 index 37802dc..0000000 --- a/components/amount/_util/animate.js +++ /dev/null @@ -1,220 +0,0 @@ -import {root} from './env' - -/* istanbul ignore file */ -const Animate = (global => { - /* istanbul ignore next */ - const time = - Date.now || - (() => { - return +new Date() - }) - const desiredFrames = 60 - const millisecondsPerSecond = 1000 - - let running = {} - let counter = 1 - - return { - /** - * A requestAnimationFrame wrapper / polyfill. - * - * @param callback {Function} The callback to be invoked before the next repaint. - * @param root {HTMLElement} The root element for the repaint - */ - requestAnimationFrame: (() => { - // Check for request animation Frame support - const requestFrame = - global.requestAnimationFrame || - global.webkitRequestAnimationFrame || - global.mozRequestAnimationFrame || - global.oRequestAnimationFrame - let isNative = !!requestFrame - - if (requestFrame && !/requestAnimationFrame\(\)\s*\{\s*\[native code\]\s*\}/i.test(requestFrame.toString())) { - isNative = false - } - - if (isNative) { - return (callback, root) => { - requestFrame(callback, root) - } - } - - const TARGET_FPS = 60 - let requests = {} - let requestCount = 0 - let rafHandle = 1 - let intervalHandle = null - let lastActive = +new Date() - - return callback => { - const callbackHandle = rafHandle++ - - // Store callback - requests[callbackHandle] = callback - requestCount++ - - // Create timeout at first request - if (intervalHandle === null) { - intervalHandle = setInterval(() => { - const time = +new Date() - const currentRequests = requests - - // Reset data structure before executing callbacks - requests = {} - requestCount = 0 - - for (const key in currentRequests) { - if (currentRequests.hasOwnProperty(key)) { - currentRequests[key](time) - lastActive = time - } - } - - // Disable the timeout when nothing happens for a certain - // period of time - if (time - lastActive > 2500) { - clearInterval(intervalHandle) - intervalHandle = null - } - }, 1000 / TARGET_FPS) - } - - return callbackHandle - } - })(), - - /** - * Stops the given animation. - * - * @param id {Integer} Unique animation ID - * @return {Boolean} Whether the animation was stopped (aka, was running before) - */ - stop(id) { - const cleared = running[id] != null - cleared && (running[id] = null) - return cleared - }, - - /** - * Whether the given animation is still running. - * - * @param id {Integer} Unique animation ID - * @return {Boolean} Whether the animation is still running - */ - isRunning(id) { - return running[id] != null - }, - - /** - * Start the animation. - * - * @param stepCallback {Function} Pointer to function which is executed on every step. - * Signature of the method should be `function(percent, now, virtual) { return continueWithAnimation; }` - * @param verifyCallback {Function} Executed before every animation step. - * Signature of the method should be `function() { return continueWithAnimation; }` - * @param completedCallback {Function} - * Signature of the method should be `function(droppedFrames, finishedAnimation) {}` - * @param duration {Integer} Milliseconds to run the animation - * @param easingMethod {Function} Pointer to easing function - * Signature of the method should be `function(percent) { return modifiedValue; }` - * @param root {Element ? document.body} Render root, when available. Used for internal - * usage of requestAnimationFrame. - * @return {Integer} Identifier of animation. Can be used to stop it any time. - */ - start(stepCallback, verifyCallback, completedCallback, duration, easingMethod, root) { - const start = time() - let lastFrame = start - let percent = 0 - let dropCounter = 0 - const id = counter++ - - if (!root) { - // root = document.body - } - - // Compacting running db automatically every few new animations - if (id % 20 === 0) { - const newRunning = {} - for (const usedId in running) { - newRunning[usedId] = true - } - running = newRunning - } - - // This is the internal step method which is called every few milliseconds - const step = virtual => { - // Normalize virtual value - const render = virtual !== true - - // Get current time - const now = time() - - // Verification is executed before next animation step - if (!running[id] || (verifyCallback && !verifyCallback(id))) { - running[id] = null - completedCallback && - completedCallback(desiredFrames - dropCounter / ((now - start) / millisecondsPerSecond), id, false) - return - } - - // For the current rendering to apply let's update omitted steps in memory. - // This is important to bring internal state variables up-to-date with progress in time. - if (render) { - const droppedFrames = Math.round((now - lastFrame) / (millisecondsPerSecond / desiredFrames)) - 1 - for (let j = 0; j < Math.min(droppedFrames, 4); j++) { - step(true) - dropCounter++ - } - } - - // Compute percent value - if (duration) { - percent = (now - start) / duration - if (percent > 1) { - percent = 1 - } - } - - // Execute step callback, then... - let value = easingMethod ? easingMethod(percent) : percent - value = isNaN(value) ? 0 : value - if ((stepCallback(value, now, render) === false || percent === 1) && render) { - running[id] = null - completedCallback && - completedCallback( - desiredFrames - dropCounter / ((now - start) / millisecondsPerSecond), - id, - percent === 1 || duration == null, - ) - } else if (render) { - lastFrame = now - this.requestAnimationFrame(step, root) - } - } - - // Mark as running - running[id] = true - - // Init first step - this.requestAnimationFrame(step, root) - - // Return unique animation ID - return id - }, - } -})(root) - -export const easeOutCubic = pos => { - return Math.pow(pos - 1, 3) + 1 -} - -export const easeInOutCubic = pos => { - if ((pos /= 0.5) < 1) { - return 0.5 * Math.pow(pos, 3) - } - - return 0.5 * (Math.pow(pos - 2, 3) + 2) -} - -export default Animate diff --git a/components/amount/_util/dom.js b/components/amount/_util/dom.js deleted file mode 100644 index 87f687f..0000000 --- a/components/amount/_util/dom.js +++ /dev/null @@ -1,22 +0,0 @@ -import {inBrowser} from './env' - -class Dom { - appendChild() {} - removeChild() {} - querySelector() {} - addEventListener() {} - removeEventListener() {} -} - -const dom = new Dom() -let mdDocument = dom -let mdBody = dom - -mdDocument.body = mdBody - -if (inBrowser) { - // mdDocument = window.document - // mdBody = document.body -} - -export {mdDocument, mdBody, dom} diff --git a/components/amount/_util/env.js b/components/amount/_util/env.js deleted file mode 100644 index c6c175c..0000000 --- a/components/amount/_util/env.js +++ /dev/null @@ -1,18 +0,0 @@ -import Vue from 'vue' - -// Development environment -export const isProd = process.env.NODE_ENV === 'production' - -// Browser environment sniffing -export const inBrowser = !Vue.prototype.$isServer -export const UA = inBrowser -export const isAndroid = UA -export const isIOS = UA -export const root = typeof window !== 'undefined' ? window : global - - -// export const inBrowser = !Vue.prototype.$isServer || typeof window !== 'undefined' -// export const UA = inBrowser && window.navigator.userAgent.toLowerCase() -// export const isAndroid = UA && UA.indexOf('android') > 0 -// export const isIOS = UA && /iphone|ipad|ipod|ios/.test(UA) -// export const root = typeof window !== 'undefined' ? window : global \ No newline at end of file diff --git a/components/amount/_util/formate-value.js b/components/amount/_util/formate-value.js deleted file mode 100644 index 1491592..0000000 --- a/components/amount/_util/formate-value.js +++ /dev/null @@ -1,76 +0,0 @@ -export function formatValueByGapRule(gapRule, value, gap = ' ', range, isAdd = 1) { - const arr = value ? value.split('') : [] - let showValue = '' - const rule = [] - gapRule.split('|').some((n, j) => { - rule[j] = +n + (rule[j - 1] ? +rule[j - 1] : 0) - }) - let j = 0 - arr.some((n, i) => { - // Remove the excess part - if (i > rule[rule.length - 1] - 1) { - return - } - if (i > 0 && i === rule[j]) { - showValue = showValue + gap + n - j++ - } else { - showValue = showValue + '' + n - } - }) - let adapt = 0 - rule.some((n, j) => { - if (range === +n + 1 + j) { - adapt = 1 * isAdd - } - }) - range = typeof range !== 'undefined' ? (range === 0 ? 0 : range + adapt) : showValue.length - return {value: showValue, range: range} -} - -export function formatValueByGapStep(step, value, gap = ' ', direction = 'right', range, isAdd = 1, oldValue = '') { - if (value.length === 0) { - return {value, range} - } - - const arr = value && value.split('') - let _range = range - let showValue = '' - - if (direction === 'right') { - for (let j = arr.length - 1, k = 0; j >= 0; j--, k++) { - const m = arr[j] - showValue = k > 0 && k % step === 0 ? m + gap + showValue : m + '' + showValue - } - if (isAdd === 1) { - // 在添加的情况下,如果添加前字符串的长度减去新的字符串的长度为2,说明多了一个间隔符,需要调整range - if (oldValue.length - showValue.length === -2) { - _range = range + 1 - } - } else { - // 在删除情况下,如果删除前字符串的长度减去新的字符串的长度为2,说明少了一个间隔符,需要调整range - if (oldValue.length - showValue.length === 2) { - _range = range - 1 - } - // 删除到最开始,range 保持 0 - if (_range <= 0) { - _range = 0 - } - } - } else { - arr.some((n, i) => { - showValue = i > 0 && i % step === 0 ? showValue + gap + n : showValue + '' + n - }) - const adapt = range % (step + 1) === 0 ? 1 * isAdd : 0 - _range = typeof range !== 'undefined' ? (range === 0 ? 0 : range + adapt) : showValue.length - } - - return {value: showValue, range: _range} -} - -export function trimValue(value, gap = ' ') { - value = typeof value === 'undefined' ? '' : value - const reg = new RegExp(gap, 'g') - value = value.toString().replace(reg, '') - return value -} diff --git a/components/amount/_util/index.js b/components/amount/_util/index.js deleted file mode 100644 index 9451c18..0000000 --- a/components/amount/_util/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export * from './env' -export * from './dom' diff --git a/components/amount/index.vue b/components/amount/index.vue deleted file mode 100644 index a167f96..0000000 --- a/components/amount/index.vue +++ /dev/null @@ -1,139 +0,0 @@ - - - - - diff --git a/components/amount/number-capital.js b/components/amount/number-capital.js deleted file mode 100644 index e473f73..0000000 --- a/components/amount/number-capital.js +++ /dev/null @@ -1,110 +0,0 @@ -const cnNums = ['\u96f6', '\u58f9', '\u8d30', '\u53c1', '\u8086', '\u4f0d', '\u9646', '\u67d2', '\u634c', '\u7396'] - -// 拾 \u62fe 佰 \u4f70 仟 \u4edf -const cnIntRadice = ['', '\u62fe', '\u4f70', '\u4edf'] - -// 万 \u4e07 亿 \u4ebf 兆 \u5146 -const cnIntUnits = ['', '\u4e07', '\u4ebf', '兆'] - -// 角 \u89d2 分 \u5206 毫 \u6beb 厘 \u5398 -const cnDecUnits = ['\u89d2', '\u5206', '\u6beb', '\u5398'] -const cnInteger = '\u6574' // 整 \u6574 -const cnIntLast = '\u5143' // 元 \u5143 - -const cnNegative = '\u8d1f' // 负 - -// Maximum number -const maxNum = 999999999999999.9999 - -export default function(number) { - let negative - // Integral part - let integerNum - // Decimal part - let decimalNum - // Capital number - let capitalStr = '' - - let parts - - /* istanbul ignore if */ - if (number === '') { - return '' - } - - number = parseFloat(number) - - if (number < 0) { - negative = true - number = Math.abs(number) - } - - /* istanbul ignore if */ - if (number >= maxNum) { - return '' - } - - /* istanbul ignore if */ - if (number === 0) { - capitalStr = cnNums[0] + cnIntLast + cnInteger - return capitalStr - } - - // Convert to String - number += '' - - if (number.indexOf('.') === -1) { - integerNum = number - decimalNum = '' - } else { - parts = number.split('.') - integerNum = parts[0] - decimalNum = parts[1].substr(0, 4) - } - - // Convert integer part - if (parseInt(integerNum, 10) > 0) { - let zeroCount = 0 - for (let i = 0, IntLen = integerNum.length; i < IntLen; i++) { - const n = integerNum.substr(i, 1) - const p = IntLen - i - 1 - const q = p / 4 - const m = p % 4 - if (n === '0') { - zeroCount++ - } else { - if (zeroCount > 0) { - capitalStr += cnNums[0] - } - zeroCount = 0 - capitalStr += cnNums[parseInt(n)] + cnIntRadice[m] - } - if (m === 0 && zeroCount < 4) { - capitalStr += cnIntUnits[q] - } - } - capitalStr += cnIntLast - } - - // Convert decimal part - if (decimalNum !== '') { - for (let i = 0, decLen = decimalNum.length; i < decLen; i++) { - const n = decimalNum.substr(i, 1) - if (n !== '0') { - capitalStr += cnNums[Number(n)] + cnDecUnits[i] - } - } - } - - /* istanbul ignore if */ - if (capitalStr === '') { - capitalStr += cnNums[0] + cnIntLast + cnInteger - } else if (decimalNum === '') { - capitalStr += cnInteger - } - - if (negative) { - capitalStr = `${cnNegative}${capitalStr}` - } - return capitalStr -} diff --git a/components/mescroll-uni/components/mescroll-down.css b/components/mescroll-uni/components/mescroll-down.css deleted file mode 100644 index 72bf106..0000000 --- a/components/mescroll-uni/components/mescroll-down.css +++ /dev/null @@ -1,55 +0,0 @@ -/* 下拉刷新区域 */ -.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 { - animation: mescrollDownRotate 0.6s linear infinite; -} - -@keyframes mescrollDownRotate { - 0% { - transform: rotate(0deg); - } - - 100% { - transform: rotate(360deg); - } -} \ No newline at end of file diff --git a/components/mescroll-uni/components/mescroll-down.vue b/components/mescroll-uni/components/mescroll-down.vue deleted file mode 100644 index 9fd1567..0000000 --- a/components/mescroll-uni/components/mescroll-down.vue +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - diff --git a/components/mescroll-uni/components/mescroll-empty.vue b/components/mescroll-uni/components/mescroll-empty.vue deleted file mode 100644 index e51f824..0000000 --- a/components/mescroll-uni/components/mescroll-empty.vue +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - diff --git a/components/mescroll-uni/components/mescroll-top.vue b/components/mescroll-uni/components/mescroll-top.vue deleted file mode 100644 index 5115fd8..0000000 --- a/components/mescroll-uni/components/mescroll-top.vue +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - diff --git a/components/mescroll-uni/components/mescroll-up.css b/components/mescroll-uni/components/mescroll-up.css deleted file mode 100644 index 5021b49..0000000 --- a/components/mescroll-uni/components/mescroll-up.css +++ /dev/null @@ -1,47 +0,0 @@ -/* 上拉加载区域 */ -.mescroll-upwarp { - box-sizing: border-box; - min-height: 110rpx; - padding: 0 0 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 { - animation: mescrollUpRotate 0.6s linear infinite; -} - -@keyframes mescrollUpRotate { - 0% { - transform: rotate(0deg); - } - - 100% { - transform: rotate(360deg); - } -} \ No newline at end of file diff --git a/components/mescroll-uni/components/mescroll-up.vue b/components/mescroll-uni/components/mescroll-up.vue deleted file mode 100644 index 11c2e1f..0000000 --- a/components/mescroll-uni/components/mescroll-up.vue +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - diff --git a/components/mescroll-uni/mescroll-body.css b/components/mescroll-uni/mescroll-body.css deleted file mode 100644 index 9cfa255..0000000 --- a/components/mescroll-uni/mescroll-body.css +++ /dev/null @@ -1,14 +0,0 @@ -.mescroll-body { - position: relative; /* 下拉刷新区域相对自身定位 */ - height: auto; /* 不可固定高度,否则overflow:hidden导致无法滑动; 同时使设置的最小高生效,实现列表不满屏仍可下拉*/ - overflow: hidden; /* 当有元素写在mescroll-body标签前面时,可遮住下拉刷新区域 */ - box-sizing: border-box; /* 避免设置padding出现双滚动条的问题 */ -} - -/* 适配 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); - } -} \ No newline at end of file diff --git a/components/mescroll-uni/mescroll-body.vue b/components/mescroll-uni/mescroll-body.vue deleted file mode 100644 index f6e3929..0000000 --- a/components/mescroll-uni/mescroll-body.vue +++ /dev/null @@ -1,339 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/components/mescroll-uni/mescroll-empty.png b/components/mescroll-uni/mescroll-empty.png deleted file mode 100644 index 5e08600..0000000 Binary files a/components/mescroll-uni/mescroll-empty.png and /dev/null differ diff --git a/components/mescroll-uni/mescroll-mixins.js b/components/mescroll-uni/mescroll-mixins.js deleted file mode 100644 index a051ac6..0000000 --- a/components/mescroll-uni/mescroll-mixins.js +++ /dev/null @@ -1,74 +0,0 @@ -// mescroll-body 和 mescroll-uni 通用 - -// import MescrollUni from "./mescroll-uni.vue"; -// import MescrollBody from "./mescroll-body.vue"; - -const MescrollMixin = { - // components: { // 非H5端无法通过mixin注册组件, 只能在main.js中注册全局组件或具体界面中注册 - // MescrollUni, - // MescrollBody - // }, - data() { - return { - mescroll: null, //mescroll实例对象 - // 上拉 - upOpt: { - - }, - // 下拉 - downOpt: { - auto: false, - inOffsetRate: 0.9 - }, - } - }, - // 注册系统自带的下拉刷新 (配置down.native为true时生效, 还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例) - onPullDownRefresh(){ - this.mescroll && this.mescroll.onPullDownRefresh(); - }, - // 注册列表滚动事件,用于判定在顶部可下拉刷新,在指定位置可显示隐藏回到顶部按钮 (此方法为页面生命周期,无法在子组件中触发, 仅在mescroll-body生效) - onPageScroll(e) { - this.mescroll && this.mescroll.onPageScroll(e); - }, - // 注册滚动到底部的事件,用于上拉加载 (此方法为页面生命周期,无法在子组件中触发, 仅在mescroll-body生效) - onReachBottom() { - this.mescroll && this.mescroll.onReachBottom(); - }, - methods: { - // mescroll组件初始化的回调,可获取到mescroll对象 - mescrollInit(mescroll) { - this.mescroll = mescroll; - this.mescrollInitByRef(); // 兼容字节跳动小程序 - }, - // 以ref的方式初始化mescroll对象 (兼容字节跳动小程序: http://www.mescroll.com/qa.html?v=20200107#q26) - mescrollInitByRef() { - if(!this.mescroll || !this.mescroll.resetUpScroll){ - let mescrollRef = this.$refs.mescrollRef; - if(mescrollRef) this.mescroll = mescrollRef.mescroll - } - }, - // 下拉刷新的回调 (mixin默认resetUpScroll) - downCallback() { - if(this.mescroll.optUp.use){ - this.mescroll.resetUpScroll() - }else{ - setTimeout(()=>{ - this.mescroll.endSuccess(); - }, 500) - } - }, - // 上拉加载的回调 - upCallback() { - // mixin默认延时500自动结束加载 - setTimeout(()=>{ - this.mescroll.endErr(); - }, 500) - } - }, - mounted() { - this.mescrollInitByRef(); // 兼容字节跳动小程序, 避免未设置@init或@init此时未能取到ref的情况 - } - -} - -export default MescrollMixin; diff --git a/components/mescroll-uni/mescroll-uni-option.js b/components/mescroll-uni/mescroll-uni-option.js deleted file mode 100644 index 4967902..0000000 --- a/components/mescroll-uni/mescroll-uni-option.js +++ /dev/null @@ -1,33 +0,0 @@ -// 全局配置 -// mescroll-body 和 mescroll-uni 通用 -const GlobalOption = { - down: { - // 其他down的配置参数也可以写,这里只展示了常用的配置: - textInOffset: '下拉刷新', // 下拉的距离在offset范围内的提示文本 - textOutOffset: '释放更新', // 下拉的距离大于offset范围的提示文本 - textLoading: '加载中 ...', // 加载中的提示文本 - offset: 80, // 在列表顶部,下拉大于80px,松手即可触发下拉刷新的回调 - native: false // 是否使用系统自带的下拉刷新; 默认false; 仅在mescroll-body生效 (值为true时,还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例) - }, - up: { - // 其他up的配置参数也可以写,这里只展示了常用的配置: - textLoading: '加载中 ...', // 加载中的提示文本 - textNoMore: '没有更多数据啦~', // 没有更多数据的提示文本 - offset: 80, // 距底部多远时,触发upCallback - toTop: { - // 回到顶部按钮,需配置src才显示 - src: "http://www.mescroll.com/img/mescroll-totop.png?v=1", // 图片路径 (建议放入static目录, 如 /static/img/mescroll-totop.png ) - offset: 1000, // 列表滚动多少距离才显示回到顶部按钮,默认1000px - right: 20, // 到右边的距离, 默认20 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx) - bottom: 120, // 到底部的距离, 默认120 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx) - width: 72 // 回到顶部图标的宽度, 默认72 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx) - }, - empty: { - use: true, // 是否显示空布局 - icon: require('./mescroll-empty.png'), // 图标路径 (建议放入static目录, 如 /static/img/mescroll-empty.png ) - tip: '暂无相关数据' // 提示 - } - } -} - -export default GlobalOption diff --git a/components/mescroll-uni/mescroll-uni.css b/components/mescroll-uni/mescroll-uni.css deleted file mode 100644 index 39438cd..0000000 --- a/components/mescroll-uni/mescroll-uni.css +++ /dev/null @@ -1,36 +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); - } -} diff --git a/components/mescroll-uni/mescroll-uni.js b/components/mescroll-uni/mescroll-uni.js deleted file mode 100644 index 76a5ac5..0000000 --- a/components/mescroll-uni/mescroll-uni.js +++ /dev/null @@ -1,788 +0,0 @@ -/* mescroll - * version 1.3.1 - * 2020-07-27 wenju - * http://www.mescroll.com - */ - -export default function MeScroll(options, isScrollBody) { - let me = this; - me.version = '1.3.1'; // mescroll版本号 - me.options = options || {}; // 配置 - me.isScrollBody = isScrollBody || false; // 滚动区域是否为原生页面滚动; 默认为scroll-view - - me.isDownScrolling = false; // 是否在执行下拉刷新的回调 - me.isUpScrolling = false; // 是否在执行上拉加载的回调 - let hasDownCallback = me.options.down && me.options.down.callback; // 是否配置了down的callback - - // 初始化下拉刷新 - me.initDownScroll(); - // 初始化上拉加载,则初始化 - me.initUpScroll(); - - // 自动加载 - setTimeout(function() { // 待主线程执行完毕再执行,避免new MeScroll未初始化,在回调获取不到mescroll的实例 - // 自动触发下拉刷新 (只有配置了down的callback才自动触发下拉刷新) - 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){ // 部分小程序(头条小程序)emit是异步, 会导致isUpAutoLoad判断有误, 先延时确保先执行down的callback,再执行up的callback - setTimeout(function(){ - me.optUp.use && me.optUp.auto && !me.isUpAutoLoad && me.triggerUpScroll(); - },100) - } - }, 30); // 需让me.optDown.inited和me.optUp.inited先执行 -} - -/* 配置参数:下拉刷新 */ -MeScroll.prototype.extendDownScroll = function(optDown) { - // 下拉刷新的配置 - MeScroll.extend(optDown, { - use: true, // 是否启用下拉刷新; 默认true - auto: true, // 是否在初始化完毕之后自动执行下拉刷新的回调; 默认true - native: false, // 是否使用系统自带的下拉刷新; 默认false; 仅mescroll-body生效 (值为true时,还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例) - autoShowLoading: false, // 如果设置auto=true(在初始化完毕之后自动执行下拉刷新的回调),那么是否显示下拉刷新的进度; 默认false - isLock: false, // 是否锁定下拉刷新,默认false; - offset: 80, // 在列表顶部,下拉大于80px,松手即可触发下拉刷新的回调 - startTop: 100, // scroll-view快速滚动到顶部时,此时的scroll-top可能大于0, 此值用于控制最大的误差 - inOffsetRate: 1, // 在列表顶部,下拉的距离小于offset时,改变下拉区域高度比例;值小于1且越接近0,高度变化越小,表现为越往下越难拉 - outOffsetRate: 0.2, // 在列表顶部,下拉的距离大于offset时,改变下拉区域高度比例;值小于1且越接近0,高度变化越小,表现为越往下越难拉 - bottomOffset: 20, // 当手指touchmove位置在距离body底部20px范围内的时候结束上拉刷新,避免Webview嵌套导致touchend事件不执行 - minAngle: 45, // 向下滑动最少偏移的角度,取值区间 [0,90];默认45度,即向下滑动的角度大于45度则触发下拉;而小于45度,将不触发下拉,避免与左右滑动的轮播等组件冲突; - textInOffset: '下拉刷新', // 下拉的距离在offset范围内的提示文本 - textOutOffset: '释放更新', // 下拉的距离大于offset范围的提示文本 - textLoading: '加载中 ...', // 加载中的提示文本 - bgColor: "transparent", // 背景颜色 (建议在pages.json中再设置一下backgroundColorTop) - textColor: "gray", // 文本颜色 (当bgColor配置了颜色,而textColor未配置时,则textColor会默认为白色) - inited: null, // 下拉刷新初始化完毕的回调 - inOffset: null, // 下拉的距离进入offset范围内那一刻的回调 - outOffset: null, // 下拉的距离大于offset那一刻的回调 - onMoving: null, // 下拉过程中的回调,滑动过程一直在执行; rate下拉区域当前高度与指定距离的比值(inOffset: rate<1; outOffset: rate>=1); downHight当前下拉区域的高度 - beforeLoading: null, // 准备触发下拉刷新的回调: 如果return true,将不触发showLoading和callback回调; 常用来完全自定义下拉刷新, 参考案例【淘宝 v6.8.0】 - showLoading: null, // 显示下拉刷新进度的回调 - afterLoading: null, // 显示下拉刷新进度的回调之后,马上要执行的代码 (如: 在wxs中使用) - beforeEndDownScroll: null, // 准备结束下拉的回调. 返回结束下拉的延时执行时间,默认0ms; 常用于结束下拉之前再显示另外一小段动画,才去隐藏下拉刷新的场景, 参考案例【dotJump】 - endDownScroll: null, // 结束下拉刷新的回调 - afterEndDownScroll: null, // 结束下拉刷新的回调,马上要执行的代码 (如: 在wxs中使用) - callback: function(mescroll) { - // 下拉刷新的回调;默认重置上拉加载列表为第一页 - mescroll.resetUpScroll(); - } - }) -} - -/* 配置参数:上拉加载 */ -MeScroll.prototype.extendUpScroll = function(optUp) { - // 上拉加载的配置 - MeScroll.extend(optUp, { - use: true, // 是否启用上拉加载; 默认true - auto: true, // 是否在初始化完毕之后自动执行上拉加载的回调; 默认true - isLock: false, // 是否锁定上拉加载,默认false; - isBoth: true, // 上拉加载时,如果滑动到列表顶部是否可以同时触发下拉刷新;默认true,两者可同时触发; - callback: null, // 上拉加载的回调;function(page,mescroll){ } - page: { - num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始 - size: 10, // 每页数据的数量 - time: null // 加载第一页数据服务器返回的时间; 防止用户翻页时,后台新增了数据从而导致下一页数据重复; - }, - noMoreSize: 5, // 如果列表已无数据,可设置列表的总数量要大于等于5条才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看 - offset: 80, // 距底部多远时,触发upCallback - textLoading: '加载中 ...', // 加载中的提示文本 - textNoMore: '没有更多数据啦~', // 没有更多数据的提示文本 - bgColor: "transparent", // 背景颜色 (建议在pages.json中再设置一下backgroundColorBottom) - textColor: "gray", // 文本颜色 (当bgColor配置了颜色,而textColor未配置时,则textColor会默认为白色) - inited: null, // 初始化完毕的回调 - showLoading: null, // 显示加载中的回调 - showNoMore: null, // 显示无更多数据的回调 - hideUpScroll: null, // 隐藏上拉加载的回调 - errDistance: 60, // endErr的时候需往上滑动一段距离,使其往下滑动时再次触发onReachBottom,仅mescroll-body生效 - toTop: { - // 回到顶部按钮,需配置src才显示 - src: null, // 图片路径,默认null (绝对路径或网络图) - offset: 1000, // 列表滚动多少距离才显示回到顶部按钮,默认1000 - duration: 300, // 回到顶部的动画时长,默认300ms (当值为0或300则使用系统自带回到顶部,更流畅; 其他值则通过step模拟,部分机型可能不够流畅,所以非特殊情况不建议修改此项) - btnClick: null, // 点击按钮的回调 - onShow: null, // 是否显示的回调 - zIndex: 9990, // fixed定位z-index值 - left: null, // 到左边的距离, 默认null. 此项有值时,right不生效. (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx) - right: 20, // 到右边的距离, 默认20 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx) - bottom: 120, // 到底部的距离, 默认120 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx) - safearea: false, // bottom的偏移量是否加上底部安全区的距离, 默认false, 需要适配iPhoneX时使用 (具体的界面如果不配置此项,则取本vue的safearea值) - width: 72, // 回到顶部图标的宽度, 默认72 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx) - radius: "50%" // 圆角, 默认"50%" (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx) - }, - empty: { - use: true, // 是否显示空布局 - icon: null, // 图标路径 - tip: '暂无相关数据', // 提示 - btnText: '', // 按钮 - btnClick: null, // 点击按钮的回调 - onShow: null, // 是否显示的回调 - fixed: false, // 是否使用fixed定位,默认false; 配置fixed为true,以下的top和zIndex才生效 (transform会使fixed失效,最终会降级为absolute) - top: "100rpx", // fixed定位的top值 (完整的单位值,如 "10%"; "100rpx") - zIndex: 99 // fixed定位z-index值 - }, - 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"; // 当bgColor有值且textColor未设置,则textColor默认白色 - me.extendDownScroll(me.optDown); - - // 如果是mescroll-body且配置了native,则禁止自定义的下拉刷新 - if(me.isScrollBody && me.optDown.native){ - me.optDown.use = false - }else{ - me.optDown.native = false // 仅mescroll-body支持,mescroll-uni不支持 - } - - me.downHight = 0; // 下拉区域的高度 - - // 在页面中加入下拉布局 - if (me.optDown.use && me.optDown.inited) { - // 初始化完毕的回调 - setTimeout(function() { // 待主线程执行完毕再执行,避免new MeScroll未初始化,在回调获取不到mescroll的实例 - me.optDown.inited(me); - }, 0) - } -} - -/* 列表touchstart事件 */ -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; // 重置上次move的点 - this.maxTouchmoveY = this.getBodyHeight() - this.optDown.bottomOffset; // 手指触摸的最大范围(写在touchstart避免body获取高度为0的情况) - this.inTouchend = false; // 标记不是touchend -} - -/* 列表touchmove事件 */ -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; // 和起点比,移动的距离,大于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.optUp.isBoth))) { - - // 下拉的初始角度是否在配置的范围内 - if(!me.startAngle) me.startAngle = me.getAngle(me.lastPoint, curPoint); // 两点之间的角度,区间 [0,90] - if (me.startAngle < me.optDown.minAngle) return; // 如果小于配置的角度,则不往下执行下拉刷新 - - // 如果手指的位置超过配置的距离,则提前结束下拉,避免Webview嵌套导致touchend无法触发 - if (me.maxTouchmoveY > 0 && curPoint.y >= me.maxTouchmoveY) { - me.inTouchend = true; // 标记执行touchend - me.touchendEvent(); // 提前触发touchend - return; - } - - me.preventDefault(e); // 阻止默认事件 - - let 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.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.isMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来 - } - 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; // 记录本次移动的点 -} - -/* 列表touchend事件 */ -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) { // scroll-view到顶/左/右/底的滑动事件 - let isScrollUp = this.getPoint(e).y - this.startPoint.y < 0; // 和起点比,移动的距离,大于0向下拉,小于0向上拉 - // 上滑 - if (isScrollUp) { - // 需检查滑动的角度 - let angle = this.getAngle(this.getPoint(e), this.startPoint); // 两点之间的角度,区间 [0,90] - 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 - } - } -} - -/* 计算两点之间的角度: 区间 [0,90]*/ -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)) { - //return true则处于完全自定义状态 - } 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); // 仍触发showLoading,因为上拉加载用到 - } 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); // 仍触发showLoading,因为上拉加载用到 - 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) // scroll-view重置滚动区域,使数据不满屏时仍可检查触发翻页 - me.scrollTo(0,0) // scroll-view需重置滚动条到顶部,避免startTop大于0时,对下拉刷新的影响 - } - } - // 结束下拉刷新时的回调 - let delay = 0; - if (me.optDown.beforeEndDownScroll) delay = me.optDown.beforeEndDownScroll(me); // 结束下拉刷新的延时,单位ms - 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); -} - -/* 锁定下拉刷新:isLock=ture,null锁定;isLock=false解锁 */ -MeScroll.prototype.lockDownScroll = function(isLock) { - if (isLock == null) isLock = true; - this.optDown.isLock = isLock; -} - -/* 锁定上拉加载:isLock=ture,null锁定;isLock=false解锁 */ -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"; // 当bgColor有值且textColor未设置,则textColor默认白色 - me.extendUpScroll(me.optUp); - - if (me.optUp.use === false) return; // 配置不使用上拉加载时,则不初始化上拉布局 - me.optUp.hasNext = true; // 如果使用上拉,则默认有下一页 - me.startNum = me.optUp.page.num + 1; // 记录page开始的页码 - - // 初始化完毕的回调 - if (me.optUp.inited) { - setTimeout(function() { // 待主线程执行完毕再执行,避免new MeScroll未初始化,在回调获取不到mescroll的实例 - me.optUp.inited(me); - }, 0) - } -} - -/*滚动到底部的事件 (仅mescroll-body生效)*/ -MeScroll.prototype.onReachBottom = function() { - if (this.isScrollBody && !this.isUpScrolling) { // 只能支持下拉刷新的时候同时可以触发上拉加载,否则滚动到底部就需要上滑一点才能触发onReachBottom - if (!this.optUp.isLock && this.optUp.hasNext) { - this.triggerUpScroll(); - } - } -} - -/*列表滚动事件 (仅mescroll-body生效)*/ -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; // 把最新的页数赋值在mescroll上,避免对page的影响 - this.size = this.optUp.page.size; // 把最新的页码赋值在mescroll上,避免对page的影响 - this.time = this.optUp.page.time; // 把最新的页码赋值在mescroll上,避免对page的影响 - 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) { // isShowNoMore=null,不处理下拉状态,下拉刷新的时候调用 - if (isShowNoMore) { - this.showNoMore(); // isShowNoMore=true,显示无更多数据 - } else { - this.hideUpScroll(); // isShowNoMore=false,隐藏上拉加载 - } - } - 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) { // 如果不是下拉刷新触发的resetUpScroll并且不配置列表静默更新,则显示进度; - if (isShowLoading == null) { - this.removeEmpty(); // 移除空布局 - this.showUpScroll(); // 不传参,默认显示上拉加载的进度布局 - } else { - this.showDownScroll(); // 传true,显示下拉刷新的进度布局,不清空列表 - } - } - this.isUpAutoLoad = true; // 标记上拉已经自动执行过,避免初始化时多次触发上拉回调 - this.num = page.num; // 把最新的页数赋值在mescroll上,避免对page的影响 - this.size = page.size; // 把最新的页码赋值在mescroll上,避免对page的影响 - this.time = page.time; // 把最新的页码赋值在mescroll上,避免对page的影响 - this.optUp.callback && this.optUp.callback(this); // 执行上拉回调 - } -} - -/* 设置page.num的值 */ -MeScroll.prototype.setPageNum = function(num) { - this.optUp.page.num = num - 1; -} - -/* 设置page.size的值 */ -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.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) { - 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); - // 如果是mescroll-body,则需往回滚一定距离 - if(this.isScrollBody && errDistance !== 0){ // 不处理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) // scrollview需自定义回到顶部方法 -} - -/* 自定义scrollTo */ -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; // 时长 300ms - rate = rate || 30; // 周期 30ms - 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); // 最后一次直接设置end,避免计算误差 - clearInterval(timer); - } - }, rate); -} - -/* 滚动容器的高度 */ -MeScroll.prototype.getClientHeight = function(isReal) { - let h = this.clientHeight || 0 - if (h === 0 && isReal !== true) { // 未获取到容器的高度,可临时取body的高度 (可能会有误差) - 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; -} - -/* body的高度 */ -MeScroll.prototype.getBodyHeight = function() { - return this.bodyHeight || 0; -} -MeScroll.prototype.setBodyHeight = function(h) { - this.bodyHeight = h; -} - -/* 阻止浏览器默认滚动事件 */ -MeScroll.prototype.preventDefault = function(e) { - // 小程序不支持e.preventDefault, 已在wxs中禁止 - // app的bounce只能通过配置pages.json的style.app-plus.bounce为"none"来禁止, 或使用renderjs禁止 - // cancelable:是否可以被禁用; defaultPrevented:是否已经被禁用 - if (e && e.cancelable && !e.defaultPrevented) e.preventDefault() -} \ No newline at end of file diff --git a/components/mescroll-uni/mescroll-uni.vue b/components/mescroll-uni/mescroll-uni.vue deleted file mode 100644 index 5186d8c..0000000 --- a/components/mescroll-uni/mescroll-uni.vue +++ /dev/null @@ -1,424 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/components/mescroll-uni/mixins/mescroll-comp.js b/components/mescroll-uni/mixins/mescroll-comp.js deleted file mode 100644 index 6aea07b..0000000 --- a/components/mescroll-uni/mixins/mescroll-comp.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * mescroll-body写在子组件时,需通过mescroll的mixins补充子组件缺少的生命周期: - * 当一个页面只有一个mescroll-body写在子组件时, 则使用mescroll-comp.js (参考 mescroll-comp 案例) - * 当一个页面有多个mescroll-body写在子组件时, 则使用mescroll-more.js (参考 mescroll-more 案例) - */ -const MescrollCompMixin = { - // 因为子组件无onPageScroll和onReachBottom的页面生命周期,需在页面传递进到子组件 (一级) - onPageScroll(e) { - this.handlePageScroll(e) - }, - onReachBottom() { - this.handleReachBottom() - }, - // 当down的native: true时, 还需传递此方法进到子组件 - onPullDownRefresh(){ - this.handlePullDownRefresh() - }, - // mescroll-body写在子子子...组件的情况 (多级) - data() { - return { - mescroll: { - onPageScroll: e=>{ - this.handlePageScroll(e) - }, - onReachBottom: ()=>{ - this.handleReachBottom() - }, - onPullDownRefresh: ()=>{ - this.handlePullDownRefresh() - } - } - } - }, - methods:{ - handlePageScroll(e){ - let item = this.$refs["mescrollItem"]; - if(item && item.mescroll) item.mescroll.onPageScroll(e); - }, - handleReachBottom(){ - let item = this.$refs["mescrollItem"]; - if(item && item.mescroll) item.mescroll.onReachBottom(); - }, - handlePullDownRefresh(){ - let item = this.$refs["mescrollItem"]; - if(item && item.mescroll) item.mescroll.onPullDownRefresh(); - } - } -} - -export default MescrollCompMixin; diff --git a/components/mescroll-uni/mixins/mescroll-more-item.js b/components/mescroll-uni/mixins/mescroll-more-item.js deleted file mode 100644 index 2549158..0000000 --- a/components/mescroll-uni/mixins/mescroll-more-item.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * mescroll-more-item的mixins, 仅在多个 mescroll-body 写在子组件时使用 (参考 mescroll-more 案例) - */ -const MescrollMoreItemMixin = { - // 支付宝小程序不支持props的mixin,需写在具体的页面中 - // #ifndef MP-ALIPAY - props:{ - i: Number, // 每个tab页的专属下标 - index: { // 当前tab的下标 - type: Number, - default(){ - return 0 - } - } - }, - // #endif - data() { - return { - downOption:{ - auto:false // 不自动加载 - }, - upOption:{ - auto:false // 不自动加载 - }, - isInit: false // 当前tab是否已初始化 - } - }, - watch:{ - // 监听下标的变化 - index(val){ - if (this.i === val && !this.isInit) { - this.isInit = true; // 标记为true - this.mescroll && this.mescroll.triggerDownScroll(); - } - } - }, - methods: { - // mescroll组件初始化的回调,可获取到mescroll对象 (覆盖mescroll-mixins.js的mescrollInit, 为了标记isInit) - mescrollInit(mescroll) { - this.mescroll = mescroll; - this.mescrollInitByRef && this.mescrollInitByRef(); // 兼容字节跳动小程序 - // 自动加载当前tab的数据 - if(this.i === this.index){ - this.isInit = true; // 标记为true - this.mescroll.triggerDownScroll(); - } - }, - } -} - -export default MescrollMoreItemMixin; diff --git a/components/mescroll-uni/mixins/mescroll-more.js b/components/mescroll-uni/mixins/mescroll-more.js deleted file mode 100644 index 142aa75..0000000 --- a/components/mescroll-uni/mixins/mescroll-more.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * mescroll-body写在子组件时,需通过mescroll的mixins补充子组件缺少的生命周期: - * 当一个页面只有一个mescroll-body写在子组件时, 则使用mescroll-comp.js (参考 mescroll-comp 案例) - * 当一个页面有多个mescroll-body写在子组件时, 则使用mescroll-more.js (参考 mescroll-more 案例) - */ -const MescrollMoreMixin = { - data() { - return { - tabIndex: 0 // 当前tab下标 - } - }, - // 因为子组件无onPageScroll和onReachBottom的页面生命周期,需在页面传递进到子组件 - onPageScroll(e) { - let mescroll = this.getMescroll(this.tabIndex); - mescroll && mescroll.onPageScroll(e); - }, - onReachBottom() { - let mescroll = this.getMescroll(this.tabIndex); - mescroll && mescroll.onReachBottom(); - }, - // 当down的native: true时, 还需传递此方法进到子组件 - onPullDownRefresh(){ - let mescroll = this.getMescroll(this.tabIndex); - mescroll && mescroll.onPullDownRefresh(); - }, - methods:{ - // 根据下标获取对应子组件的mescroll - getMescroll(i){ - if(!this.mescrollItems) this.mescrollItems = []; - if(!this.mescrollItems[i]) { - // v-for中的refs - let vForItem = this.$refs["mescrollItem"]; - if(vForItem){ - this.mescrollItems[i] = vForItem[i] - }else{ - // 普通的refs,不可重复 - this.mescrollItems[i] = this.$refs["mescrollItem"+i]; - } - } - let item = this.mescrollItems[i] - return item ? item.mescroll : null - }, - // 切换tab,恢复滚动条位置 - tabChange(i){ - let mescroll = this.getMescroll(i); - if(mescroll){ - // 延时(比$nextTick靠谱一些),确保元素已渲染 - setTimeout(()=>{ - mescroll.scrollTo(mescroll.getScrollTop(),0) - },30) - } - } - } -} - -export default MescrollMoreMixin; diff --git a/components/mescroll-uni/wxs/mixins.js b/components/mescroll-uni/wxs/mixins.js deleted file mode 100644 index 7f49ff7..0000000 --- a/components/mescroll-uni/wxs/mixins.js +++ /dev/null @@ -1,102 +0,0 @@ -// 定义在wxs (含renderjs) 逻辑层的数据和方法, 与视图层相互通信 -const WxsMixin = { - data() { - return { - // 传入wxs视图层的数据 (响应式) - wxsProp: { - optDown:{}, // 下拉刷新的配置 - scrollTop:0, // 滚动条的距离 - bodyHeight:0, // body的高度 - isDownScrolling:false, // 是否正在下拉刷新中 - isUpScrolling:false, // 是否正在上拉加载中 - isScrollBody:true, // 是否为mescroll-body滚动 - isUpBoth:true, // 上拉加载时,是否同时可以下拉刷新 - t: 0 // 数据更新的标记 (只有数据更新了,才会触发wxs的Observer) - }, - - // 标记调用wxs视图层的方法 - callProp: { - callType: '', // 方法名 - t: 0 // 数据更新的标记 (只有数据更新了,才会触发wxs的Observer) - }, - - // 不用wxs的平台使用此处的wxsBiz对象,抹平wxs的写法 (微信小程序和APP使用的wxsBiz对象是./wxs/wxs.wxs) - // #ifndef MP-WEIXIN || APP-PLUS || H5 - wxsBiz: { - //注册列表touchstart事件,用于下拉刷新 - touchstartEvent: e=> { - this.mescroll.touchstartEvent(e); - }, - //注册列表touchmove事件,用于下拉刷新 - touchmoveEvent: e=> { - this.mescroll.touchmoveEvent(e); - }, - //注册列表touchend事件,用于下拉刷新 - touchendEvent: e=> { - this.mescroll.touchendEvent(e); - }, - propObserver(){}, // 抹平wxs的写法 - callObserver(){} // 抹平wxs的写法 - }, - // #endif - - // 不用renderjs的平台使用此处的renderBiz对象,抹平renderjs的写法 (app 和 h5 使用的renderBiz对象是./wxs/renderjs.js) - // #ifndef APP-PLUS || H5 - renderBiz: { - propObserver(){} // 抹平renderjs的写法 - } - // #endif - } - }, - methods: { - // wxs视图层调用逻辑层的回调 - wxsCall(msg){ - if(msg.type === 'setWxsProp'){ - // 更新wxsProp数据 (值改变才触发更新) - this.wxsProp = { - optDown: this.mescroll.optDown, - scrollTop: this.mescroll.getScrollTop(), - bodyHeight: this.mescroll.getBodyHeight(), - isDownScrolling: this.mescroll.isDownScrolling, - isUpScrolling: this.mescroll.isUpScrolling, - isUpBoth: this.mescroll.optUp.isBoth, - isScrollBody:this.mescroll.isScrollBody, - t: Date.now() - } - }else if(msg.type === 'setLoadType'){ - // 设置inOffset,outOffset的状态 - this.downLoadType = msg.downLoadType - }else if(msg.type === 'triggerDownScroll'){ - // 主动触发下拉刷新 - this.mescroll.triggerDownScroll(); - }else if(msg.type === 'endDownScroll'){ - // 结束下拉刷新 - this.mescroll.endDownScroll(); - }else if(msg.type === 'triggerUpScroll'){ - // 主动触发上拉加载 - this.mescroll.triggerUpScroll(true); - } - } - }, - mounted() { - // #ifdef MP-WEIXIN || APP-PLUS || H5 - // 配置主动触发wxs显示加载进度的回调 - this.mescroll.optDown.afterLoading = ()=>{ - this.callProp = {callType: "showLoading", t: Date.now()} // 触发wxs的方法 (值改变才触发更新) - } - // 配置主动触发wxs隐藏加载进度的回调 - this.mescroll.optDown.afterEndDownScroll = ()=>{ - this.callProp = {callType: "endDownScroll", t: Date.now()} // 触发wxs的方法 (值改变才触发更新) - setTimeout(()=>{ - if(this.downLoadType === 4 || this.downLoadType === 0){ - this.callProp = {callType: "clearTransform", t: Date.now()} // 触发wxs的方法 (值改变才触发更新) - } - },320) - } - // 初始化wxs的数据 - this.wxsCall({type: 'setWxsProp'}) - // #endif - } -} - -export default WxsMixin; diff --git a/components/mescroll-uni/wxs/renderjs.js b/components/mescroll-uni/wxs/renderjs.js deleted file mode 100644 index 207f388..0000000 --- a/components/mescroll-uni/wxs/renderjs.js +++ /dev/null @@ -1,92 +0,0 @@ -// 使用renderjs直接操作window对象,实现动态控制app和h5的bounce -// bounce: iOS橡皮筋,Android半月弧,h5浏览器下拉背景等效果 (下拉刷新时禁止) -// https://uniapp.dcloud.io/frame?id=renderjs - -// 与wxs的me实例一致 -var me = {} - -// 初始化window对象的touch事件 (仅初始化一次) -if(window && !window.$mescrollRenderInit){ - window.$mescrollRenderInit = true - - - window.addEventListener('touchstart', function(e){ - if (me.disabled()) return; - me.startPoint = me.getPoint(e); // 记录起点 - }, {passive: true}) - - - window.addEventListener('touchmove', function(e){ - if (me.disabled()) return; - if (me.getScrollTop() > 0) return; // 需在顶部下拉,才禁止bounce - - var curPoint = me.getPoint(e); // 当前点 - var moveY = curPoint.y - me.startPoint.y; // 和起点比,移动的距离,大于0向下拉,小于0向上拉 - // 向下拉 - if (moveY > 0) { - // 可下拉的条件 - if (!me.isDownScrolling && !me.optDown.isLock && (!me.isUpScrolling || (me.isUpScrolling && me.isUpBoth))) { - - // 只有touch在mescroll的view上面,才禁止bounce - var el = e.target; - var isMescrollTouch = false; - while (el && el.tagName && el.tagName !== 'UNI-PAGE-BODY' && el.tagName != "BODY") { - var cls = el.classList; - if (cls && cls.contains('mescroll-render-touch')) { - isMescrollTouch = true - break; - } - el = el.parentNode; // 继续检查其父元素 - } - // 禁止bounce (不会对swiper和iOS侧滑返回造成影响) - if (isMescrollTouch && e.cancelable && !e.defaultPrevented) e.preventDefault(); - } - } - }, {passive: false}) -} - -/* 获取滚动条的位置 */ -me.getScrollTop = function() { - return me.scrollTop || 0 -} - -/* 是否禁用下拉刷新 */ -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} - } -} - -/** - * 监听逻辑层数据的变化 (实时更新数据) - */ -function propObserver(wxsProp) { - me.optDown = wxsProp.optDown - me.scrollTop = wxsProp.scrollTop - me.isDownScrolling = wxsProp.isDownScrolling - me.isUpScrolling = wxsProp.isUpScrolling - me.isUpBoth = wxsProp.isUpBoth -} - -/* 导出模块 */ -const renderBiz = { - data() { - return { - propObserver: propObserver, - } - } -} - -export default renderBiz; \ No newline at end of file diff --git a/components/mescroll-uni/wxs/wxs.wxs b/components/mescroll-uni/wxs/wxs.wxs deleted file mode 100644 index 3fb4ad9..0000000 --- a/components/mescroll-uni/wxs/wxs.wxs +++ /dev/null @@ -1,268 +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) { - 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 -} \ No newline at end of file diff --git a/pages/order/confirm-order.vue b/pages/order/confirm-order.vue index 7f3286d..a048651 100644 --- a/pages/order/confirm-order.vue +++ b/pages/order/confirm-order.vue @@ -75,9 +75,7 @@ - -