206 lines
6.3 KiB
XML
206 lines
6.3 KiB
XML
// z-paging
|
||
// github地址:https://github.com/SmileZXLee/uni-z-paging
|
||
// dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935
|
||
// 反馈QQ群:790460711
|
||
|
||
//微信小程序、QQ小程序、app-vue、h5上使用wxs实现自定义下拉刷新,降低逻辑层与视图层的通信折损,提升性能
|
||
|
||
function propObserver(newValue, oldValue, ownerInstance, instance) {
|
||
var state = ownerInstance.getState();
|
||
state.currentInstance = instance;
|
||
var dataset = instance.getDataset();
|
||
var loading = dataset.loading == true;
|
||
if (newValue.indexOf('end') != -1) {
|
||
_setTransform('translateY(0px)', instance)
|
||
state.moveDistance = 0;
|
||
} else if (newValue.indexOf('begin') != -1) {
|
||
var refresherThreshold = instance.getDataset().refresherthreshold
|
||
_setTransformValue(refresherThreshold, instance, state);
|
||
}
|
||
}
|
||
|
||
function touchstart(e, ownerInstance) {
|
||
var instance = ownerInstance.getState().currentInstance;
|
||
var state = instance.getState();
|
||
if (_getRefresherTouchDisabled(e, instance)) {
|
||
return;
|
||
}
|
||
var touch = _getCommonTouch(e);
|
||
state.startY = touch.touchY;
|
||
state.lastRefresherTouchmove = touch;
|
||
ownerInstance.callMethod('_handleRefresherTouchstart', touch);
|
||
}
|
||
|
||
function touchmove(e, ownerInstance) {
|
||
var touch = _getCommonTouch(e);
|
||
var instance = ownerInstance.getState().currentInstance;
|
||
var dataset = instance.getDataset();
|
||
var refresherThreshold = dataset.refresherthreshold;
|
||
var isTouchmoving = _getIsTrue(instance.getDataset().istouchmoving);
|
||
var state = instance.getState();
|
||
if (_getRefresherTouchDisabled(e, instance)) {
|
||
return;
|
||
}
|
||
if (!_getAngleIsInRange(e, touch, state, dataset)) {
|
||
return;
|
||
}
|
||
var moveDistance = _getMoveDistance(e, instance);
|
||
if (moveDistance < 0) {
|
||
return;
|
||
}
|
||
if (e.preventDefault) {
|
||
e.preventDefault();
|
||
}
|
||
_setTransformValue(moveDistance, instance, state);
|
||
var oldRefresherStatus = state.refresherStatus;
|
||
if (moveDistance >= refresherThreshold) {
|
||
state.refresherStatus = 1;
|
||
} else {
|
||
state.refresherStatus = 0;
|
||
}
|
||
if (oldRefresherStatus == undefined || oldRefresherStatus != state.refresherStatus || !isTouchmoving) {
|
||
ownerInstance.callMethod('_handleRefresherTouchmove', moveDistance, touch);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
function touchend(e, ownerInstance) {
|
||
var touch = _getCommonTouch(e);
|
||
var instance = ownerInstance.getState().currentInstance;
|
||
var dataset = instance.getDataset();
|
||
var state = instance.getState();
|
||
if (_getRefresherTouchDisabled(e, instance)) {
|
||
return;
|
||
}
|
||
state.refresherReachMaxAngle = true;
|
||
|
||
var isTouchmoving = _getIsTrue(instance.getDataset().istouchmoving);
|
||
if (!isTouchmoving) {
|
||
return;
|
||
}
|
||
var oldMoveDistance = state.moveDistance;
|
||
var refresherThreshold = instance.getDataset().refresherthreshold
|
||
var moveDistance = _getMoveDistance(e, instance);
|
||
ownerInstance.callMethod('_handleRefresherTouchend', moveDistance);
|
||
if (oldMoveDistance < refresherThreshold) {
|
||
return;
|
||
}
|
||
if (moveDistance >= refresherThreshold) {
|
||
moveDistance = refresherThreshold;
|
||
}
|
||
_setTransformValue(moveDistance, instance, state)
|
||
}
|
||
|
||
|
||
function _setTransformValue(value, instance, state) {
|
||
value = value || 0;
|
||
state.moveDistance = value;
|
||
_setTransform('translateY(' + value + 'px)', instance);
|
||
}
|
||
|
||
function _setTransform(transform, instance) {
|
||
instance.requestAnimationFrame(function() {
|
||
instance.setStyle({
|
||
transform: transform,
|
||
'-webkit-transform': transform
|
||
})
|
||
})
|
||
|
||
}
|
||
|
||
function _getMoveDistance(e, instance) {
|
||
var state = instance.getState()
|
||
var refresherThreshold = instance.getDataset().refresherthreshold
|
||
var touch = _getCommonTouch(e);
|
||
var moveDistance = touch.touchY - state.startY;
|
||
moveDistance = _getFinalRefresherMoveDistance(moveDistance, refresherThreshold);
|
||
return moveDistance;
|
||
}
|
||
|
||
function _getCommonTouch(e) {
|
||
var touch = null;
|
||
if (e.touches && e.touches.length) {
|
||
touch = e.touches[0];
|
||
} else if (e.changedTouches && e.changedTouches.length) {
|
||
touch = e.changedTouches[0];
|
||
} else if (e.datail && e.datail !== {}) {
|
||
touch = e.datail;
|
||
} else {
|
||
return {
|
||
touchX: 0,
|
||
touchY: 0
|
||
}
|
||
}
|
||
return {
|
||
touchX: touch.clientX,
|
||
touchY: touch.clientY
|
||
};
|
||
}
|
||
|
||
function _getFinalRefresherMoveDistance(moveDistance, refresherThreshold) {
|
||
refresherThreshold = parseFloat(refresherThreshold);
|
||
moveDistance = moveDistance * 0.7;
|
||
if (moveDistance >= refresherThreshold) {
|
||
moveDistance = refresherThreshold + (moveDistance - refresherThreshold) * 0.3;
|
||
}
|
||
return moveDistance;
|
||
}
|
||
|
||
|
||
function _getRefresherTouchDisabled(e, instance) {
|
||
var dataset = instance.getDataset();
|
||
var loading = _getIsTrue(dataset.loading);
|
||
var useChatRecordMode = _getIsTrue(dataset.usechatrecordmode);
|
||
var refresherEnabled = _getIsTrue(dataset.refresherenabled);
|
||
var useCustomRefresher = _getIsTrue(dataset.usecustomrefresher);
|
||
var usePageScroll = _getIsTrue(dataset.usepagescroll);
|
||
var pageScrollTop = parseFloat(dataset.pagescrolltop);
|
||
var wxsIsScrollTopInTopRange = _getIsTrue(dataset.wxsisscrolltopintoprange);
|
||
var scrollTop = parseFloat(dataset.scrolltop);
|
||
var res = loading || useChatRecordMode || !refresherEnabled || !useCustomRefresher || (
|
||
usePageScroll && useCustomRefresher && pageScrollTop > 10) || (!(
|
||
usePageScroll && useCustomRefresher) && !wxsIsScrollTopInTopRange);
|
||
return res;
|
||
}
|
||
|
||
function _getAngleIsInRange(e, touch, state, dataset) {
|
||
var refresherMaxAngle = dataset.refreshermaxangle;
|
||
var refresherAecc = _getIsTrue(dataset.refresheraecc);
|
||
var lastRefresherTouchmove = state.lastRefresherTouchmove;
|
||
var moveDistance = state.moveDistance;
|
||
var refresherReachMaxAngle = state.refresherReachMaxAngle;
|
||
if (!lastRefresherTouchmove) {
|
||
return true;
|
||
}
|
||
if (refresherMaxAngle >= 0 && refresherMaxAngle <= 90 && lastRefresherTouchmove) {
|
||
if (!refresherAecc && refresherReachMaxAngle != null && !refresherReachMaxAngle) {
|
||
return false;
|
||
}
|
||
var x = Math.abs(touch.touchX - lastRefresherTouchmove.touchX);
|
||
var y = Math.abs(touch.touchY - lastRefresherTouchmove.touchY);
|
||
var z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
|
||
if (x && y) {
|
||
var angle = Math.asin(y / z) / Math.PI * 180;
|
||
if (angle < refresherMaxAngle) {
|
||
state.lastRefresherTouchmove = touch;
|
||
state.refresherReachMaxAngle = false;
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
state.lastRefresherTouchmove = touch;
|
||
return true;
|
||
}
|
||
|
||
function _getIsTrue(value) {
|
||
value = (typeof(value) === 'string' ? JSON.parse(value) : value) || false;
|
||
return value == true || value == 'true';
|
||
}
|
||
|
||
module.exports = {
|
||
touchstart: touchstart,
|
||
touchmove: touchmove,
|
||
touchend: touchend,
|
||
propObserver: propObserver
|
||
}
|