overscroll
Version:
302 lines (265 loc) • 7.79 kB
JavaScript
import is from 'whatitis';
import actions from './actions';
import domUtils from './utils/dom';
import domStates from './domStates';
import animations from './animations';
import getWindow from './utils/dom/getWindow';
import getDocument from './utils/dom/getDocument';
import { handleDestroy, handleScroll, handleBeforeScroll, handleAfterScroll, handleInit } from './handlers';
var X = 'x';
var Y = 'y';
var XY = 'xy';
var xreg = /x/i;
var yreg = /y/i;
var OVERSCROLL = 'OverScroll';
var OVERSCROLLX = 'OverScrollX';
var OVERSCROLLY = 'OverScrollY';
var BUBBLE = 'bubble';
var NOBUBBLE = 'noBubble';
function hasX(axis) {
return xreg.test(axis);
}
function hasY(axis) {
return yreg.test(axis);
}
function hasXY(axis) {
return hasX(axis) && hasY(axis);
}
function getAxis() {
var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : XY;
if (hasXY(axis)) {
return XY;
} else if (hasX(axis)) {
return X;
}
return Y;
}
var getScrollByAxis = function getScrollByAxis(_ref) {
var target = _ref.target,
axis = _ref.axis,
win = _ref.win,
html = _ref.html,
body = _ref.body,
isPageScroll = _ref.isPageScroll;
return function () {
// CSS1Compat 标准模式 BackCompat 混杂模式
// const isCSS1Compat = doc.compatMode === 'CSS1Compat';
var scrollX = function scrollX() {
return !isPageScroll ? target.scrollLeft : is.Defined(win.pageXOffset) ? win.pageXOffset : Math.max(html.scrollLeft, body.scrollLeft);
};
var scrollY = function scrollY() {
return !isPageScroll ? target.scrollTop : is.Defined(win.pageYOffset) ? win.pageYOffset : Math.max(html.scrollTop, body.scrollTop);
};
if (hasXY(axis)) {
return {
top: scrollY(),
left: scrollX()
};
} else if (hasX(axis)) {
return {
top: 0,
left: scrollX()
};
}
return {
top: scrollY(),
left: 0
};
};
};
var defaultOptions = {
axis: XY,
prefix: OVERSCROLL,
thumbMiniSize: 20,
// show: true,
// showX: true,
// showY: true,
target: null,
watchInterval: 100,
watch: null,
onInit: null,
onScroll: null,
onBeforeScroll: null,
onAfterScroll: null,
onDestroy: null,
// getContainer: null,
isPageScroll: false, // 判断是否是页面滚动
mode: 'scroll', // 'section'
anchors: null,
switchScale: [0.2, 0.2], // [往上拉的距离比例,往下拉的距离比例]
position: [0, 0],
bubble: true, // 让父级的滚动可以触发
dragable: true, // pointerType === 'mouse' 的开关
touchable: true // pointerType === 'touch' 的开关
};
function getOptions() {
var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
axis = _ref2.axis,
prefix = _ref2.prefix,
target = _ref2.target,
watchInterval = _ref2.watchInterval,
watch = _ref2.watch,
onInit = _ref2.onInit,
onScroll = _ref2.onScroll,
onBeforeScroll = _ref2.onBeforeScroll,
onAfterScroll = _ref2.onAfterScroll,
onDestroy = _ref2.onDestroy,
mode = _ref2.mode,
anchors = _ref2.anchors,
switchScale = _ref2.switchScale,
position = _ref2.position,
bubble = _ref2.bubble,
dragable = _ref2.dragable,
touchable = _ref2.touchable;
var options = Object.assign({}, defaultOptions);
var doc = getDocument(target);
var win = getWindow(doc);
var body = doc.body;
var html = doc.documentElement;
// 滚动容器
if (is.Undefined(target) || [html, body].includes(target)) {
options.target = doc.scrollingElement || body;
options.isPageScroll = true;
} else {
options.target = target;
}
// 元素装载容器
// if ( target === html ) {
// // options.container = options.target === html ? body : options.target;
// options.target = body;
// } else {
// options.target = target;
// }
// container => containerX containerY
// if ( is.Function( getContainer )) {
// const container = getContainer();
// if ( is.Element( container )) {
// options.containerX = container;
// options.containerY = container;
// } else {
// const { x, y, X, Y } = container;
// options.containerX = x || X;
// options.containerY = y || Y || options.containerX;
// }
// } else {
// options.containerX = options.container;
// options.containerY = options.containerX;
// }
// 滚动条 计算
// axis => scrollX scrollY
options.axis = getAxis(axis);
options.scrollX = hasX(options.axis);
options.scrollY = hasY(options.axis);
// 滚动条 显示/隐藏
// show => showX showY
// options.show = show !== false;
// options.showX = options.show && showX !== false;
// options.showY = options.show && showY !== false;
// 样式前缀 prefix
if (is.String(prefix)) {
options.prefix = prefix;
}
// 事件
if (is.Function(onInit)) {
options.onInit = onInit;
}
// onScroll( scrollTop, scrollLeft )
if (is.Function(onScroll)) {
options.onScroll = onScroll;
}
if (is.Function(onBeforeScroll)) {
options.onBeforeScroll = onBeforeScroll;
}
if (is.Function(onAfterScroll)) {
options.onAfterScroll = onAfterScroll;
}
if (is.Function(onDestroy)) {
options.onDestroy = onDestroy;
}
if (is.Function(watch)) {
options.watch = watch;
if (is.Number(watchInterval) && watchInterval > 50) {
options.watchInterval = watchInterval;
}
}
if (is.Array(position) && position.every(is.Number)) {
options.position = position;
}
if (mode === 'section') {
options.mode = mode;
options.axis = hasY(options.axis) ? Y : X;
options.scrollX = options.axis === X;
options.scrollY = options.axis === Y;
options.position = is.Number(position) ? position : 1;
if (is.Array(anchors) && anchors.every(is.Element)) {
options.anchors = anchors;
} else {
options.anchors = Array.prototype.slice.call(target.children);
}
if (is.String(switchScale) && /^\d*$/.test(switchScale)) {
switchScale = [parseFloat(switchScale), parseFloat(switchScale)];
}
if (is.Number(switchScale)) {
switchScale = [switchScale, switchScale];
}
if (is.Array(switchScale) && anchors.every(function (num) {
return is.Number(num) && num <= 1 && num >= 0;
})) {
options.switchScale = [].concat(switchScale);
}
}
// 设置当前滚动区间是否冒泡事件
if (bubble === false) {
options.bubble = bubble;
}
// 鼠标拖动开关
if (dragable === false) {
options.dragable = dragable;
}
// 触摸开关
if (touchable === false) {
options.touchable = touchable;
}
return Object.assign(options, { body: body, html: html, doc: doc, win: win });
}
export default (function (options) {
var overscroll = {
scrollTop: 0,
scrollLeft: 0,
scrollHeight: 0,
scrollWidth: 0,
clientHeight: 0,
clientWidth: 0,
section: 1,
scrolling: false
};
var scope = {
X: X,
Y: Y,
XY: XY,
xreg: xreg,
yreg: yreg,
hasX: hasX,
hasY: hasY,
hasXY: hasXY,
OVERSCROLL: OVERSCROLL,
OVERSCROLLX: OVERSCROLLX,
OVERSCROLLY: OVERSCROLLY,
BUBBLE: BUBBLE,
NOBUBBLE: NOBUBBLE,
overscroll: overscroll
};
Object.assign(scope, getOptions(options));
Object.assign(scope, domUtils(scope), {
getScroll: getScrollByAxis(scope),
handleDestroy: handleDestroy(scope),
handleBeforeScroll: handleBeforeScroll(scope),
handleAfterScroll: handleAfterScroll(scope),
handleScroll: handleScroll(scope),
handleInit: handleInit(scope)
});
Object.assign(scope, domStates(scope));
Object.assign(scope, actions(scope));
Object.assign(scope, animations(scope));
return scope;
});