UNPKG

overscroll

Version:
302 lines (265 loc) 7.79 kB
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; });