You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
285 lines
9.7 KiB
285 lines
9.7 KiB
/*!
|
|
* better-scroll / pull-down
|
|
* (c) 2016-2020 ustbhuangyi
|
|
* Released under the MIT License.
|
|
*/
|
|
// ssr support
|
|
var inBrowser = typeof window !== 'undefined';
|
|
var ua = inBrowser && navigator.userAgent.toLowerCase();
|
|
var isWeChatDevTools = !!(ua && /wechatdevtools/.test(ua));
|
|
var isAndroid = ua && ua.indexOf('android') > 0;
|
|
/* istanbul ignore next */
|
|
var isIOSBadVersion = (function () {
|
|
if (typeof ua === 'string') {
|
|
var regex = /os (\d\d?_\d(_\d)?)/;
|
|
var matches = regex.exec(ua);
|
|
if (!matches)
|
|
return false;
|
|
var parts = matches[1].split('_').map(function (item) {
|
|
return parseInt(item, 10);
|
|
});
|
|
// ios version >= 13.4 issue 982
|
|
return !!(parts[0] >= 13 && parts[1] >= 4);
|
|
}
|
|
return false;
|
|
})();
|
|
|
|
var extend = function (target, source) {
|
|
for (var key in source) {
|
|
target[key] = source[key];
|
|
}
|
|
return target;
|
|
};
|
|
|
|
var elementStyle = (inBrowser &&
|
|
document.createElement('div').style);
|
|
var vendor = (function () {
|
|
/* istanbul ignore if */
|
|
if (!inBrowser) {
|
|
return false;
|
|
}
|
|
var transformNames = [
|
|
{
|
|
key: 'standard',
|
|
value: 'transform',
|
|
},
|
|
{
|
|
key: 'webkit',
|
|
value: 'webkitTransform',
|
|
},
|
|
{
|
|
key: 'Moz',
|
|
value: 'MozTransform',
|
|
},
|
|
{
|
|
key: 'O',
|
|
value: 'OTransform',
|
|
},
|
|
{
|
|
key: 'ms',
|
|
value: 'msTransform',
|
|
},
|
|
];
|
|
for (var _i = 0, transformNames_1 = transformNames; _i < transformNames_1.length; _i++) {
|
|
var obj = transformNames_1[_i];
|
|
if (elementStyle[obj.value] !== undefined) {
|
|
return obj.key;
|
|
}
|
|
}
|
|
/* istanbul ignore next */
|
|
return false;
|
|
})();
|
|
/* istanbul ignore next */
|
|
function prefixStyle(style) {
|
|
if (vendor === false) {
|
|
return style;
|
|
}
|
|
if (vendor === 'standard') {
|
|
if (style === 'transitionEnd') {
|
|
return 'transitionend';
|
|
}
|
|
return style;
|
|
}
|
|
return vendor + style.charAt(0).toUpperCase() + style.substr(1);
|
|
}
|
|
var cssVendor = vendor && vendor !== 'standard' ? '-' + vendor.toLowerCase() + '-' : '';
|
|
var transform = prefixStyle('transform');
|
|
var transition = prefixStyle('transition');
|
|
var hasPerspective = inBrowser && prefixStyle('perspective') in elementStyle;
|
|
var style = {
|
|
transform: transform,
|
|
transition: transition,
|
|
transitionTimingFunction: prefixStyle('transitionTimingFunction'),
|
|
transitionDuration: prefixStyle('transitionDuration'),
|
|
transitionDelay: prefixStyle('transitionDelay'),
|
|
transformOrigin: prefixStyle('transformOrigin'),
|
|
transitionEnd: prefixStyle('transitionEnd'),
|
|
transitionProperty: prefixStyle('transitionProperty'),
|
|
};
|
|
|
|
var ease = {
|
|
// easeOutQuint
|
|
swipe: {
|
|
style: 'cubic-bezier(0.23, 1, 0.32, 1)',
|
|
fn: function (t) {
|
|
return 1 + --t * t * t * t * t;
|
|
}
|
|
},
|
|
// easeOutQuard
|
|
swipeBounce: {
|
|
style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
|
|
fn: function (t) {
|
|
return t * (2 - t);
|
|
}
|
|
},
|
|
// easeOutQuart
|
|
bounce: {
|
|
style: 'cubic-bezier(0.165, 0.84, 0.44, 1)',
|
|
fn: function (t) {
|
|
return 1 - --t * t * t * t;
|
|
}
|
|
}
|
|
};
|
|
|
|
var sourcePrefix = 'plugins.pullDownRefresh';
|
|
var propertiesMap = [
|
|
{
|
|
key: 'finishPullDown',
|
|
name: 'finishPullDown'
|
|
},
|
|
{
|
|
key: 'openPullDown',
|
|
name: 'openPullDown'
|
|
},
|
|
{
|
|
key: 'closePullDown',
|
|
name: 'closePullDown'
|
|
},
|
|
{
|
|
key: 'autoPullDownRefresh',
|
|
name: 'autoPullDownRefresh'
|
|
}
|
|
];
|
|
var propertiesConfig = propertiesMap.map(function (item) {
|
|
return {
|
|
key: item.key,
|
|
sourceKey: sourcePrefix + "." + item.name
|
|
};
|
|
});
|
|
|
|
var PULL_DOWN_HOOKS_NAME = 'pullingDown';
|
|
var PullDown = /** @class */ (function () {
|
|
function PullDown(scroll) {
|
|
this.scroll = scroll;
|
|
this.pulling = false;
|
|
this.init();
|
|
}
|
|
PullDown.prototype.init = function () {
|
|
this.handleBScroll();
|
|
this.handleOptions(this.scroll.options.pullDownRefresh);
|
|
this.handleHooks();
|
|
this.watch();
|
|
};
|
|
PullDown.prototype.handleBScroll = function () {
|
|
this.scroll.registerType([PULL_DOWN_HOOKS_NAME]);
|
|
this.scroll.proxy(propertiesConfig);
|
|
};
|
|
PullDown.prototype.handleOptions = function (userOptions) {
|
|
if (userOptions === void 0) { userOptions = {}; }
|
|
userOptions = (userOptions === true ? {} : userOptions);
|
|
var defaultOptions = {
|
|
threshold: 90,
|
|
stop: 40,
|
|
};
|
|
this.options = extend(defaultOptions, userOptions);
|
|
// plugin relies on scrollTo api
|
|
// set it to Realtime make bs dispatch scroll、scrollEnd hooks
|
|
this.scroll.options.probeType = 3 /* Realtime */;
|
|
};
|
|
PullDown.prototype.handleHooks = function () {
|
|
var _this = this;
|
|
this.hooksFn = [];
|
|
var scroller = this.scroll.scroller;
|
|
var scrollBehaviorY = scroller.scrollBehaviorY;
|
|
this.currentMinScrollY = this.cachedOriginanMinScrollY =
|
|
scrollBehaviorY.minScrollPos;
|
|
this.registerHooks(this.scroll.hooks, this.scroll.hooks.eventTypes.contentChanged, function () {
|
|
_this.finishPullDown();
|
|
});
|
|
this.registerHooks(scrollBehaviorY.hooks, scrollBehaviorY.hooks.eventTypes.computeBoundary, function (boundary) {
|
|
// content is smaller than wrapper
|
|
if (boundary.maxScrollPos > 0) {
|
|
// allow scrolling when content is not full of wrapper
|
|
boundary.maxScrollPos = -1;
|
|
}
|
|
boundary.minScrollPos = _this.currentMinScrollY;
|
|
});
|
|
// integrate with mousewheel
|
|
if (this.scroll.eventTypes.alterOptions) {
|
|
this.registerHooks(this.scroll, this.scroll.eventTypes.alterOptions, function (mouseWheelOptions) {
|
|
var SANE_DISCRETE_TIME = 300;
|
|
var SANE_EASE_TIME = 350;
|
|
mouseWheelOptions.discreteTime = SANE_DISCRETE_TIME;
|
|
// easeTime > discreteTime ensure goInto checkPullDown function
|
|
mouseWheelOptions.easeTime = SANE_EASE_TIME;
|
|
});
|
|
this.registerHooks(this.scroll, this.scroll.eventTypes.mousewheelEnd, function () {
|
|
// mouseWheel need trigger checkPullDown manually
|
|
scroller.hooks.trigger(scroller.hooks.eventTypes.end);
|
|
});
|
|
}
|
|
};
|
|
PullDown.prototype.registerHooks = function (hooks, name, handler) {
|
|
hooks.on(name, handler, this);
|
|
this.hooksFn.push([hooks, name, handler]);
|
|
};
|
|
PullDown.prototype.watch = function () {
|
|
var scroller = this.scroll.scroller;
|
|
this.watching = true;
|
|
this.registerHooks(scroller.hooks, scroller.hooks.eventTypes.end, this.checkPullDown);
|
|
};
|
|
PullDown.prototype.unwatch = function () {
|
|
var scroller = this.scroll.scroller;
|
|
this.watching = false;
|
|
scroller.hooks.off(scroller.hooks.eventTypes.end, this.checkPullDown);
|
|
};
|
|
PullDown.prototype.checkPullDown = function () {
|
|
var _a = this.options, threshold = _a.threshold, stop = _a.stop;
|
|
// check if a real pull down action
|
|
if (this.scroll.y < threshold) {
|
|
return false;
|
|
}
|
|
if (!this.pulling) {
|
|
this.modifyBehaviorYBoundary(stop);
|
|
this.pulling = true;
|
|
this.scroll.trigger(PULL_DOWN_HOOKS_NAME);
|
|
}
|
|
this.scroll.scrollTo(this.scroll.x, stop, this.scroll.options.bounceTime, ease.bounce);
|
|
return this.pulling;
|
|
};
|
|
PullDown.prototype.modifyBehaviorYBoundary = function (stopDistance) {
|
|
var scrollBehaviorY = this.scroll.scroller.scrollBehaviorY;
|
|
// manually modify minScrollPos for a hang animation
|
|
// to prevent from resetPosition
|
|
this.cachedOriginanMinScrollY = scrollBehaviorY.minScrollPos;
|
|
this.currentMinScrollY = stopDistance;
|
|
scrollBehaviorY.computeBoundary();
|
|
};
|
|
PullDown.prototype.finishPullDown = function () {
|
|
if (this.pulling === true) {
|
|
var scrollBehaviorY = this.scroll.scroller.scrollBehaviorY;
|
|
// restore minScrollY since the hang animation has ended
|
|
this.currentMinScrollY = this.cachedOriginanMinScrollY;
|
|
scrollBehaviorY.computeBoundary();
|
|
this.pulling = false;
|
|
this.scroll.resetPosition(this.scroll.options.bounceTime, ease.bounce);
|
|
}
|
|
};
|
|
// allow 'true' type is compat for beta version implements
|
|
PullDown.prototype.openPullDown = function (config) {
|
|
if (config === void 0) { config = {}; }
|
|
this.handleOptions(config);
|
|
if (!this.watching) {
|
|
this.watch();
|
|
}
|
|
};
|
|
PullDown.prototype.closePullDown = function () {
|
|
this.unwatch();
|
|
};
|
|
PullDown.prototype.autoPullDownRefresh = function () {
|
|
var _a = this.options, threshold = _a.threshold, stop = _a.stop;
|
|
if (this.pulling || !this.watching) {
|
|
return;
|
|
}
|
|
this.pulling = true;
|
|
this.modifyBehaviorYBoundary(stop);
|
|
this.scroll.scrollTo(this.scroll.x, threshold);
|
|
this.scroll.trigger(PULL_DOWN_HOOKS_NAME);
|
|
this.scroll.scrollTo(this.scroll.x, stop, this.scroll.options.bounceTime, ease.bounce);
|
|
};
|
|
PullDown.pluginName = 'pullDownRefresh';
|
|
return PullDown;
|
|
}());
|
|
|
|
export default PullDown;
|