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

/*!
* 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;