UNPKG

cube-ui

Version:

A fantastic mobile ui lib implement by Vue

1,789 lines (1,531 loc) 96.2 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["better-scroll"] = factory(); else root["cube"] = root["cube"] || {}, root["cube"]["better-scroll"] = factory(); })(typeof self !== 'undefined' ? self : this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = "./"; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 282); /******/ }) /************************************************************************/ /******/ ({ /***/ 282: /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function (global, factory) { if (true) { !(__WEBPACK_AMD_DEFINE_ARRAY__ = [module, exports, __webpack_require__(90)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } else if (typeof exports !== "undefined") { factory(module, exports, require('better-scroll')); } else { var mod = { exports: {} }; factory(mod, mod.exports, global.betterScroll); global.index = mod.exports; } })(this, function (module, exports, _betterScroll) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _betterScroll2 = _interopRequireDefault(_betterScroll); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = _betterScroll2.default; module.exports = exports['default']; }); /***/ }), /***/ 90: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); /*! * better-normal-scroll v1.12.6 * (c) 2016-2018 ustbhuangyi * Released under the MIT License. */ var slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var toConsumableArray = function (arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }; function eventMixin(BScroll) { BScroll.prototype.on = function (type, fn) { var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this; if (!this._events[type]) { this._events[type] = []; } this._events[type].push([fn, context]); }; BScroll.prototype.once = function (type, fn) { var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this; function magic() { this.off(type, magic); fn.apply(context, arguments); } // To expose the corresponding function method in order to execute the off method magic.fn = fn; this.on(type, magic); }; BScroll.prototype.off = function (type, fn) { var _events = this._events[type]; if (!_events) { return; } var count = _events.length; while (count--) { if (_events[count][0] === fn || _events[count][0] && _events[count][0].fn === fn) { _events[count][0] = undefined; } } }; BScroll.prototype.trigger = function (type) { var events = this._events[type]; if (!events) { return; } var len = events.length; var eventsCopy = [].concat(toConsumableArray(events)); for (var i = 0; i < len; i++) { var event = eventsCopy[i]; var _event = slicedToArray(event, 2), fn = _event[0], context = _event[1]; if (fn) { fn.apply(context, [].slice.call(arguments, 1)); } } }; } // 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; function getNow() { return window.performance && window.performance.now ? window.performance.now() + window.performance.timing.navigationStart : +new Date(); } function extend(target) { for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { rest[_key - 1] = arguments[_key]; } for (var i = 0; i < rest.length; i++) { var source = rest[i]; for (var key in source) { target[key] = source[key]; } } return target; } function isUndef(v) { return v === undefined || v === null; } function getDistance(x, y) { return Math.sqrt(x * x + y * y); } var elementStyle = inBrowser && document.createElement('div').style; var vendor = function () { if (!inBrowser) { return false; } var transformNames = { webkit: 'webkitTransform', Moz: 'MozTransform', O: 'OTransform', ms: 'msTransform', standard: 'transform' }; for (var key in transformNames) { if (elementStyle[transformNames[key]] !== undefined) { return key; } } return false; }(); function prefixStyle(style) { if (vendor === false) { return false; } if (vendor === 'standard') { if (style === 'transitionEnd') { return 'transitionend'; } return style; } return vendor + style.charAt(0).toUpperCase() + style.substr(1); } function addEvent(el, type, fn, capture) { el.addEventListener(type, fn, { passive: false, capture: !!capture }); } function removeEvent(el, type, fn, capture) { el.removeEventListener(type, fn, { passive: false, capture: !!capture }); } function offset(el) { var left = 0; var top = 0; while (el) { left -= el.offsetLeft; top -= el.offsetTop; el = el.offsetParent; } return { left: left, top: top }; } function offsetToBody(el) { var rect = el.getBoundingClientRect(); return { left: -(rect.left + window.pageXOffset), top: -(rect.top + window.pageYOffset) }; } var transform = prefixStyle('transform'); var hasPerspective = inBrowser && prefixStyle('perspective') in elementStyle; // fix issue #361 var hasTouch = inBrowser && ('ontouchstart' in window || isWeChatDevTools); var hasTransform = transform !== false; var hasTransition = inBrowser && prefixStyle('transition') in elementStyle; var style = { transform: transform, transitionTimingFunction: prefixStyle('transitionTimingFunction'), transitionDuration: prefixStyle('transitionDuration'), transitionDelay: prefixStyle('transitionDelay'), transformOrigin: prefixStyle('transformOrigin'), transitionEnd: prefixStyle('transitionEnd') }; var TOUCH_EVENT = 1; var MOUSE_EVENT = 2; var eventType = { touchstart: TOUCH_EVENT, touchmove: TOUCH_EVENT, touchend: TOUCH_EVENT, mousedown: MOUSE_EVENT, mousemove: MOUSE_EVENT, mouseup: MOUSE_EVENT }; function getRect(el) { if (el instanceof window.SVGElement) { var rect = el.getBoundingClientRect(); return { top: rect.top, left: rect.left, width: rect.width, height: rect.height }; } else { return { top: el.offsetTop, left: el.offsetLeft, width: el.offsetWidth, height: el.offsetHeight }; } } function preventDefaultException(el, exceptions) { for (var i in exceptions) { if (exceptions[i].test(el[i])) { return true; } } return false; } function tap(e, eventName) { var ev = document.createEvent('Event'); ev.initEvent(eventName, true, true); ev.pageX = e.pageX; ev.pageY = e.pageY; e.target.dispatchEvent(ev); } function click(e) { var event = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'click'; var eventSource = void 0; if (e.type === 'mouseup' || e.type === 'mousecancel') { eventSource = e; } else if (e.type === 'touchend' || e.type === 'touchcancel') { eventSource = e.changedTouches[0]; } var posSrc = {}; if (eventSource) { posSrc.screenX = eventSource.screenX || 0; posSrc.screenY = eventSource.screenY || 0; posSrc.clientX = eventSource.clientX || 0; posSrc.clientY = eventSource.clientY || 0; } var ev = void 0; var bubbles = true; var cancelable = true; if (typeof MouseEvent !== 'undefined') { try { ev = new MouseEvent(event, extend({ bubbles: bubbles, cancelable: cancelable }, posSrc)); } catch (e) { createEvent(); } } else { createEvent(); } function createEvent() { ev = document.createEvent('Event'); ev.initEvent(event, bubbles, cancelable); extend(ev, posSrc); } // forwardedTouchEvent set to true in case of the conflict with fastclick ev.forwardedTouchEvent = true; ev._constructed = true; e.target.dispatchEvent(ev); } function dblclick(e) { click(e, 'dblclick'); } function prepend(el, target) { if (target.firstChild) { before(el, target.firstChild); } else { target.appendChild(el); } } function before(el, target) { target.parentNode.insertBefore(el, target); } function removeChild(el, child) { el.removeChild(child); } var DEFAULT_OPTIONS = { startX: 0, startY: 0, scrollX: false, scrollY: true, freeScroll: false, directionLockThreshold: 5, eventPassthrough: '', click: false, tap: false, /** * support any side * bounce: { * top: true, * bottom: true, * left: true, * right: true * } */ bounce: true, bounceTime: 800, momentum: true, momentumLimitTime: 300, momentumLimitDistance: 15, swipeTime: 2500, swipeBounceTime: 500, deceleration: 0.0015, flickLimitTime: 200, flickLimitDistance: 100, resizePolling: 60, probeType: 0, preventDefault: true, preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/ }, HWCompositing: true, useTransition: true, useTransform: true, bindToWrapper: false, disableMouse: hasTouch, disableTouch: !hasTouch, observeDOM: true, autoBlur: true, /** * for picker * wheel: { * selectedIndex: 0, * rotate: 25, * adjustTime: 400 * wheelWrapperClass: 'wheel-scroll', * wheelItemClass: 'wheel-item' * } */ wheel: false, /** * for slide * snap: { * loop: false, * el: domEl, * threshold: 0.1, * stepX: 100, * stepY: 100, * speed: 400, * easing: { * style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', * fn: function (t) { * return t * (2 - t) * } * } * listenFlick: true * } */ snap: false, /** * for scrollbar * scrollbar: { * fade: true, * interactive: false * } */ scrollbar: false, /** * for pull down and refresh * pullDownRefresh: { * threshold: 50, * stop: 20 * } */ pullDownRefresh: false, /** * for pull up and load * pullUpLoad: { * threshold: 50 * } */ pullUpLoad: false, /** * for mouse wheel * mouseWheel: { * speed: 20, * invert: false, * easeTime: 300 * } */ mouseWheel: false, stopPropagation: false, /** * for zoom * zoom: { * start: 1, * min: 1, * max: 4 * } */ zoom: false, /** * for infinity * infinity: { * render(item, div) { * }, * createTombstone() { * }, * fetch(count) { * } * } */ infinity: false, /** * for double click * dblclick: { * delay: 300 * } */ dblclick: false }; function initMixin(BScroll) { BScroll.prototype._init = function (el, options) { this._handleOptions(options); // init private custom events this._events = {}; this.x = 0; this.y = 0; this.directionX = 0; this.directionY = 0; this.setScale(1); this._addDOMEvents(); this._initExtFeatures(); this._watchTransition(); if (this.options.observeDOM) { this._initDOMObserver(); } if (this.options.autoBlur) { this._handleAutoBlur(); } this.refresh(); if (!this.options.snap) { this.scrollTo(this.options.startX, this.options.startY); } this.enable(); }; BScroll.prototype.setScale = function (scale) { this.lastScale = isUndef(this.scale) ? scale : this.scale; this.scale = scale; }; BScroll.prototype._handleOptions = function (options) { this.options = extend({}, DEFAULT_OPTIONS, options); this.translateZ = this.options.HWCompositing && hasPerspective ? ' translateZ(0)' : ''; this.options.useTransition = this.options.useTransition && hasTransition; this.options.useTransform = this.options.useTransform && hasTransform; this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault; // If you want eventPassthrough I have to lock one of the axes this.options.scrollX = this.options.eventPassthrough === 'horizontal' ? false : this.options.scrollX; this.options.scrollY = this.options.eventPassthrough === 'vertical' ? false : this.options.scrollY; // With eventPassthrough we also need lockDirection mechanism this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough; this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold; if (this.options.tap === true) { this.options.tap = 'tap'; } }; BScroll.prototype._addDOMEvents = function () { var eventOperation = addEvent; this._handleDOMEvents(eventOperation); }; BScroll.prototype._removeDOMEvents = function () { var eventOperation = removeEvent; this._handleDOMEvents(eventOperation); }; BScroll.prototype._handleDOMEvents = function (eventOperation) { var target = this.options.bindToWrapper ? this.wrapper : window; eventOperation(window, 'orientationchange', this); eventOperation(window, 'resize', this); if (this.options.click) { eventOperation(this.wrapper, 'click', this, true); } if (!this.options.disableMouse) { eventOperation(this.wrapper, 'mousedown', this); eventOperation(target, 'mousemove', this); eventOperation(target, 'mousecancel', this); eventOperation(target, 'mouseup', this); } if (hasTouch && !this.options.disableTouch) { eventOperation(this.wrapper, 'touchstart', this); eventOperation(target, 'touchmove', this); eventOperation(target, 'touchcancel', this); eventOperation(target, 'touchend', this); } eventOperation(this.scroller, style.transitionEnd, this); }; BScroll.prototype._initExtFeatures = function () { if (this.options.snap) { this._initSnap(); } if (this.options.scrollbar) { this._initScrollbar(); } if (this.options.pullUpLoad) { this._initPullUp(); } if (this.options.pullDownRefresh) { this._initPullDown(); } if (this.options.wheel) { this._initWheel(); } if (this.options.mouseWheel) { this._initMouseWheel(); } if (this.options.zoom) { this._initZoom(); } if (this.options.infinity) { this._initInfinite(); } }; BScroll.prototype._watchTransition = function () { if (typeof Object.defineProperty !== 'function') { return; } var me = this; var isInTransition = false; var key = this.useTransition ? 'isInTransition' : 'isAnimating'; Object.defineProperty(this, key, { get: function get() { return isInTransition; }, set: function set(newVal) { isInTransition = newVal; // fix issue #359 var el = me.scroller.children.length ? me.scroller.children : [me.scroller]; var pointerEvents = isInTransition && !me.pulling ? 'none' : 'auto'; for (var i = 0; i < el.length; i++) { el[i].style.pointerEvents = pointerEvents; } } }); }; BScroll.prototype._handleAutoBlur = function () { this.on('scrollStart', function () { var activeElement = document.activeElement; if (activeElement && (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA')) { activeElement.blur(); } }); }; BScroll.prototype._initDOMObserver = function () { var _this = this; if (typeof MutationObserver !== 'undefined') { var timer = void 0; var observer = new MutationObserver(function (mutations) { // don't do any refresh during the transition, or outside of the boundaries if (_this._shouldNotRefresh()) { return; } var immediateRefresh = false; var deferredRefresh = false; for (var i = 0; i < mutations.length; i++) { var mutation = mutations[i]; if (mutation.type !== 'attributes') { immediateRefresh = true; break; } else { if (mutation.target !== _this.scroller) { deferredRefresh = true; break; } } } if (immediateRefresh) { _this.refresh(); } else if (deferredRefresh) { // attributes changes too often clearTimeout(timer); timer = setTimeout(function () { if (!_this._shouldNotRefresh()) { _this.refresh(); } }, 60); } }); var config = { attributes: true, childList: true, subtree: true }; observer.observe(this.scroller, config); this.on('destroy', function () { observer.disconnect(); }); } else { this._checkDOMUpdate(); } }; BScroll.prototype._shouldNotRefresh = function () { var outsideBoundaries = this.x > this.minScrollX || this.x < this.maxScrollX || this.y > this.minScrollY || this.y < this.maxScrollY; return this.isInTransition || this.stopFromTransition || outsideBoundaries; }; BScroll.prototype._checkDOMUpdate = function () { var scrollerRect = getRect(this.scroller); var oldWidth = scrollerRect.width; var oldHeight = scrollerRect.height; function check() { if (this.destroyed) { return; } scrollerRect = getRect(this.scroller); var newWidth = scrollerRect.width; var newHeight = scrollerRect.height; if (oldWidth !== newWidth || oldHeight !== newHeight) { this.refresh(); } oldWidth = newWidth; oldHeight = newHeight; next.call(this); } function next() { var _this2 = this; setTimeout(function () { check.call(_this2); }, 1000); } next.call(this); }; BScroll.prototype.handleEvent = function (e) { switch (e.type) { case 'touchstart': case 'mousedown': this._start(e); if (this.options.zoom && e.touches && e.touches.length > 1) { this._zoomStart(e); } break; case 'touchmove': case 'mousemove': if (this.options.zoom && e.touches && e.touches.length > 1) { this._zoom(e); } else { this._move(e); } break; case 'touchend': case 'mouseup': case 'touchcancel': case 'mousecancel': if (this.scaled) { this._zoomEnd(e); } else { this._end(e); } break; case 'orientationchange': case 'resize': this._resize(); break; case 'transitionend': case 'webkitTransitionEnd': case 'oTransitionEnd': case 'MSTransitionEnd': this._transitionEnd(e); break; case 'click': if (this.enabled && !e._constructed) { if (!preventDefaultException(e.target, this.options.preventDefaultException)) { e.preventDefault(); e.stopPropagation(); } } break; case 'wheel': case 'DOMMouseScroll': case 'mousewheel': this._onMouseWheel(e); break; } }; BScroll.prototype.refresh = function () { var isWrapperStatic = window.getComputedStyle(this.wrapper, null).position === 'static'; var wrapperRect = getRect(this.wrapper); this.wrapperWidth = wrapperRect.width; this.wrapperHeight = wrapperRect.height; var scrollerRect = getRect(this.scroller); this.scrollerWidth = Math.round(scrollerRect.width * this.scale); this.scrollerHeight = Math.round(scrollerRect.height * this.scale); this.relativeX = scrollerRect.left; this.relativeY = scrollerRect.top; if (isWrapperStatic) { this.relativeX -= wrapperRect.left; this.relativeY -= wrapperRect.top; } this.minScrollX = 0; this.minScrollY = 0; var wheel = this.options.wheel; if (wheel) { this.items = this.scroller.children; this.options.itemHeight = this.itemHeight = this.items.length ? this.scrollerHeight / this.items.length : 0; if (this.selectedIndex === undefined) { this.selectedIndex = wheel.selectedIndex || 0; } this.options.startY = -this.selectedIndex * this.itemHeight; this.maxScrollX = 0; this.maxScrollY = -this.itemHeight * (this.items.length - 1); } else { this.maxScrollX = this.wrapperWidth - this.scrollerWidth; if (!this.options.infinity) { this.maxScrollY = this.wrapperHeight - this.scrollerHeight; } if (this.maxScrollX < 0) { this.maxScrollX -= this.relativeX; this.minScrollX = -this.relativeX; } else if (this.scale > 1) { this.maxScrollX = this.maxScrollX / 2 - this.relativeX; this.minScrollX = this.maxScrollX; } if (this.maxScrollY < 0) { this.maxScrollY -= this.relativeY; this.minScrollY = -this.relativeY; } else if (this.scale > 1) { this.maxScrollY = this.maxScrollY / 2 - this.relativeY; this.minScrollY = this.maxScrollY; } } this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < this.minScrollX; this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < this.minScrollY; if (!this.hasHorizontalScroll) { this.maxScrollX = this.minScrollX; this.scrollerWidth = this.wrapperWidth; } if (!this.hasVerticalScroll) { this.maxScrollY = this.minScrollY; this.scrollerHeight = this.wrapperHeight; } this.endTime = 0; this.directionX = 0; this.directionY = 0; this.wrapperOffset = offset(this.wrapper); this.trigger('refresh'); !this.scaled && this.resetPosition(); }; BScroll.prototype.enable = function () { this.enabled = true; }; BScroll.prototype.disable = function () { this.enabled = false; }; } var ease = { // easeOutQuint swipe: { style: 'cubic-bezier(0.23, 1, 0.32, 1)', fn: function fn(t) { return 1 + --t * t * t * t * t; } }, // easeOutQuard swipeBounce: { style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', fn: function fn(t) { return t * (2 - t); } }, // easeOutQuart bounce: { style: 'cubic-bezier(0.165, 0.84, 0.44, 1)', fn: function fn(t) { return 1 - --t * t * t * t; } } }; function momentum(current, start, time, lowerMargin, upperMargin, wrapperSize, options) { var distance = current - start; var speed = Math.abs(distance) / time; var deceleration = options.deceleration, itemHeight = options.itemHeight, swipeBounceTime = options.swipeBounceTime, wheel = options.wheel, swipeTime = options.swipeTime; var duration = swipeTime; var rate = wheel ? 4 : 15; var destination = current + speed / deceleration * (distance < 0 ? -1 : 1); if (wheel && itemHeight) { destination = Math.round(destination / itemHeight) * itemHeight; } if (destination < lowerMargin) { destination = wrapperSize ? Math.max(lowerMargin - wrapperSize / 4, lowerMargin - wrapperSize / rate * speed) : lowerMargin; duration = swipeBounceTime; } else if (destination > upperMargin) { destination = wrapperSize ? Math.min(upperMargin + wrapperSize / 4, upperMargin + wrapperSize / rate * speed) : upperMargin; duration = swipeBounceTime; } return { destination: Math.round(destination), duration: duration }; } var DEFAULT_INTERVAL = 100 / 60; function noop() {} var requestAnimationFrame = function () { if (!inBrowser) { /* istanbul ignore if */ return noop; } return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || // if all else fails, use setTimeout function (callback) { return window.setTimeout(callback, (callback.interval || DEFAULT_INTERVAL) / 2); // make interval as precise as possible. }; }(); var cancelAnimationFrame = function () { if (!inBrowser) { /* istanbul ignore if */ return noop; } return window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || function (id) { window.clearTimeout(id); }; }(); var DIRECTION_UP = 1; var DIRECTION_DOWN = -1; var DIRECTION_LEFT = 1; var DIRECTION_RIGHT = -1; var PROBE_DEBOUNCE = 1; var PROBE_REALTIME = 3; function warn(msg) { console.error('[BScroll warn]: ' + msg); } function assert(condition, msg) { if (!condition) { throw new Error('[BScroll] ' + msg); } } function coreMixin(BScroll) { BScroll.prototype._start = function (e) { var _eventType = eventType[e.type]; if (_eventType !== TOUCH_EVENT) { if (e.button !== 0) { return; } } if (!this.enabled || this.destroyed || this.initiated && this.initiated !== _eventType) { return; } this.initiated = _eventType; if (this.options.preventDefault && !preventDefaultException(e.target, this.options.preventDefaultException)) { e.preventDefault(); } if (this.options.stopPropagation) { e.stopPropagation(); } this.moved = false; this.distX = 0; this.distY = 0; this.directionX = 0; this.directionY = 0; this.movingDirectionX = 0; this.movingDirectionY = 0; this.directionLocked = 0; this._transitionTime(); this.startTime = getNow(); if (this.options.wheel) { this.target = e.target; } this.stop(); var point = e.touches ? e.touches[0] : e; this.startX = this.x; this.startY = this.y; this.absStartX = this.x; this.absStartY = this.y; this.pointX = point.pageX; this.pointY = point.pageY; this.trigger('beforeScrollStart'); }; BScroll.prototype._move = function (e) { if (!this.enabled || this.destroyed || eventType[e.type] !== this.initiated) { return; } if (this.options.preventDefault) { e.preventDefault(); } if (this.options.stopPropagation) { e.stopPropagation(); } var point = e.touches ? e.touches[0] : e; var deltaX = point.pageX - this.pointX; var deltaY = point.pageY - this.pointY; this.pointX = point.pageX; this.pointY = point.pageY; this.distX += deltaX; this.distY += deltaY; var absDistX = Math.abs(this.distX); var absDistY = Math.abs(this.distY); var timestamp = getNow(); // We need to move at least momentumLimitDistance pixels for the scrolling to initiate if (timestamp - this.endTime > this.options.momentumLimitTime && absDistY < this.options.momentumLimitDistance && absDistX < this.options.momentumLimitDistance) { return; } // If you are scrolling in one direction lock the other if (!this.directionLocked && !this.options.freeScroll) { if (absDistX > absDistY + this.options.directionLockThreshold) { this.directionLocked = 'h'; // lock horizontally } else if (absDistY >= absDistX + this.options.directionLockThreshold) { this.directionLocked = 'v'; // lock vertically } else { this.directionLocked = 'n'; // no lock } } if (this.directionLocked === 'h') { if (this.options.eventPassthrough === 'vertical') { e.preventDefault(); } else if (this.options.eventPassthrough === 'horizontal') { this.initiated = false; return; } deltaY = 0; } else if (this.directionLocked === 'v') { if (this.options.eventPassthrough === 'horizontal') { e.preventDefault(); } else if (this.options.eventPassthrough === 'vertical') { this.initiated = false; return; } deltaX = 0; } deltaX = this.hasHorizontalScroll ? deltaX : 0; deltaY = this.hasVerticalScroll ? deltaY : 0; this.movingDirectionX = deltaX > 0 ? DIRECTION_RIGHT : deltaX < 0 ? DIRECTION_LEFT : 0; this.movingDirectionY = deltaY > 0 ? DIRECTION_DOWN : deltaY < 0 ? DIRECTION_UP : 0; var newX = this.x + deltaX; var newY = this.y + deltaY; var top = false; var bottom = false; var left = false; var right = false; // Slow down or stop if outside of the boundaries var bounce = this.options.bounce; if (bounce !== false) { top = bounce.top === undefined ? true : bounce.top; bottom = bounce.bottom === undefined ? true : bounce.bottom; left = bounce.left === undefined ? true : bounce.left; right = bounce.right === undefined ? true : bounce.right; } if (newX > this.minScrollX || newX < this.maxScrollX) { if (newX > this.minScrollX && left || newX < this.maxScrollX && right) { newX = this.x + deltaX / 3; } else { newX = newX > this.minScrollX ? this.minScrollX : this.maxScrollX; } } if (newY > this.minScrollY || newY < this.maxScrollY) { if (newY > this.minScrollY && top || newY < this.maxScrollY && bottom) { newY = this.y + deltaY / 3; } else { newY = newY > this.minScrollY ? this.minScrollY : this.maxScrollY; } } if (!this.moved) { this.moved = true; this.trigger('scrollStart'); } this._translate(newX, newY); if (timestamp - this.startTime > this.options.momentumLimitTime) { this.startTime = timestamp; this.startX = this.x; this.startY = this.y; if (this.options.probeType === PROBE_DEBOUNCE) { this.trigger('scroll', { x: this.x, y: this.y }); } } if (this.options.probeType > PROBE_DEBOUNCE) { this.trigger('scroll', { x: this.x, y: this.y }); } var scrollLeft = document.documentElement.scrollLeft || window.pageXOffset || document.body.scrollLeft; var scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop; var pX = this.pointX - scrollLeft; var pY = this.pointY - scrollTop; if (pX > document.documentElement.clientWidth - this.options.momentumLimitDistance || pX < this.options.momentumLimitDistance || pY < this.options.momentumLimitDistance || pY > document.documentElement.clientHeight - this.options.momentumLimitDistance) { this._end(e); } }; BScroll.prototype._end = function (e) { if (!this.enabled || this.destroyed || eventType[e.type] !== this.initiated) { return; } this.initiated = false; if (this.options.preventDefault && !preventDefaultException(e.target, this.options.preventDefaultException)) { e.preventDefault(); } if (this.options.stopPropagation) { e.stopPropagation(); } this.trigger('touchEnd', { x: this.x, y: this.y }); this.isInTransition = false; // ensures that the last position is rounded var newX = Math.round(this.x); var newY = Math.round(this.y); var deltaX = newX - this.absStartX; var deltaY = newY - this.absStartY; this.directionX = deltaX > 0 ? DIRECTION_RIGHT : deltaX < 0 ? DIRECTION_LEFT : 0; this.directionY = deltaY > 0 ? DIRECTION_DOWN : deltaY < 0 ? DIRECTION_UP : 0; // if configure pull down refresh, check it first if (this.options.pullDownRefresh && this._checkPullDown()) { return; } // check if it is a click operation if (this._checkClick(e)) { this.trigger('scrollCancel'); return; } // reset if we are outside of the boundaries if (this.resetPosition(this.options.bounceTime, ease.bounce)) { return; } this._translate(newX, newY); this.endTime = getNow(); var duration = this.endTime - this.startTime; var absDistX = Math.abs(newX - this.startX); var absDistY = Math.abs(newY - this.startY); // flick if (this._events.flick && duration < this.options.flickLimitTime && absDistX < this.options.flickLimitDistance && absDistY < this.options.flickLimitDistance) { this.trigger('flick'); return; } var time = 0; // start momentum animation if needed if (this.options.momentum && duration < this.options.momentumLimitTime && (absDistY > this.options.momentumLimitDistance || absDistX > this.options.momentumLimitDistance)) { var top = false; var bottom = false; var left = false; var right = false; var bounce = this.options.bounce; if (bounce !== false) { top = bounce.top === undefined ? true : bounce.top; bottom = bounce.bottom === undefined ? true : bounce.bottom; left = bounce.left === undefined ? true : bounce.left; right = bounce.right === undefined ? true : bounce.right; } var wrapperWidth = this.directionX === DIRECTION_RIGHT && left || this.directionX === DIRECTION_LEFT && right ? this.wrapperWidth : 0; var wrapperHeight = this.directionY === DIRECTION_DOWN && top || this.directionY === DIRECTION_UP && bottom ? this.wrapperHeight : 0; var momentumX = this.hasHorizontalScroll ? momentum(this.x, this.startX, duration, this.maxScrollX, this.minScrollX, wrapperWidth, this.options) : { destination: newX, duration: 0 }; var momentumY = this.hasVerticalScroll ? momentum(this.y, this.startY, duration, this.maxScrollY, this.minScrollY, wrapperHeight, this.options) : { destination: newY, duration: 0 }; newX = momentumX.destination; newY = momentumY.destination; time = Math.max(momentumX.duration, momentumY.duration); this.isInTransition = true; } else { if (this.options.wheel) { newY = Math.round(newY / this.itemHeight) * this.itemHeight; time = this.options.wheel.adjustTime || 400; } } var easing = ease.swipe; if (this.options.snap) { var snap = this._nearestSnap(newX, newY); this.currentPage = snap; time = this.options.snapSpeed || Math.max(Math.max(Math.min(Math.abs(newX - snap.x), 1000), Math.min(Math.abs(newY - snap.y), 1000)), 300); newX = snap.x; newY = snap.y; this.directionX = 0; this.directionY = 0; easing = this.options.snap.easing || ease.bounce; } if (newX !== this.x || newY !== this.y) { // change easing function when scroller goes out of the boundaries if (newX > this.minScrollX || newX < this.maxScrollX || newY > this.minScrollY || newY < this.maxScrollY) { easing = ease.swipeBounce; } this.scrollTo(newX, newY, time, easing); return; } if (this.options.wheel) { this.selectedIndex = Math.round(Math.abs(this.y / this.itemHeight)); } this.trigger('scrollEnd', { x: this.x, y: this.y }); }; BScroll.prototype._checkClick = function (e) { // when in the process of pulling down, it should not prevent click var preventClick = this.stopFromTransition && !this.pulling; this.stopFromTransition = false; // we scrolled less than 15 pixels if (!this.moved) { if (this.options.wheel) { if (this.target && this.target.classList.contains(this.options.wheel.wheelWrapperClass)) { var index = Math.abs(Math.round(this.y / this.itemHeight)); var _offset = Math.round((this.pointY + offsetToBody(this.wrapper).top - this.wrapperHeight / 2) / this.itemHeight); this.target = this.items[index + _offset]; } this.scrollToElement(this.target, this.options.wheel.adjustTime || 400, true, true, ease.swipe); return true; } else { if (!preventClick) { var _dblclick = this.options.dblclick; var dblclickTrigged = false; if (_dblclick && this.lastClickTime) { var _dblclick$delay = _dblclick.delay, delay = _dblclick$delay === undefined ? 300 : _dblclick$delay; if (getNow() - this.lastClickTime < delay) { dblclickTrigged = true; dblclick(e); } } if (this.options.tap) { tap(e, this.options.tap); } if (this.options.click && !preventDefaultException(e.target, this.options.preventDefaultException)) { click(e); } this.lastClickTime = dblclickTrigged ? null : getNow(); return true; } return false; } } return false; }; BScroll.prototype._resize = function () { var _this = this; if (!this.enabled) { return; } // fix a scroll problem under Android condition if (isAndroid) { this.wrapper.scrollTop = 0; } clearTimeout(this.resizeTimeout); this.resizeTimeout = setTimeout(function () { _this.refresh(); }, this.options.resizePolling); }; BScroll.prototype._startProbe = function () { cancelAnimationFrame(this.probeTimer); this.probeTimer = requestAnimationFrame(probe); var me = this; function probe() { var pos = me.getComputedPosition(); me.trigger('scroll', pos); if (!me.isInTransition) { me.trigger('scrollEnd', pos); return; } me.probeTimer = requestAnimationFrame(probe); } }; BScroll.prototype._transitionTime = function () { var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; this.scrollerStyle[style.transitionDuration] = time + 'ms'; if (this.options.wheel) { for (var i = 0; i < this.items.length; i++) { this.items[i].style[style.transitionDuration] = time + 'ms'; } } if (this.indicators) { for (var _i = 0; _i < this.indicators.length; _i++) { this.indicators[_i].transitionTime(time); } } }; BScroll.prototype._transitionTimingFunction = function (easing) { this.scrollerStyle[style.transitionTimingFunction] = easing; if (this.options.wheel) { for (var i = 0; i < this.items.length; i++) { this.items[i].style[style.transitionTimingFunction] = easing; } } if (this.indicators) { for (var _i2 = 0; _i2 < this.indicators.length; _i2++) { this.indicators[_i2].transitionTimingFunction(easing); } } }; BScroll.prototype._transitionEnd = function (e) { if (e.target !== this.scroller || !this.isInTransition) { return; } this._transitionTime(); var needReset = !this.pulling || this.movingDirectionY === DIRECTION_UP; if (needReset && !this.resetPosition(this.options.bounceTime, ease.bounce)) { this.isInTransition = false; if (this.options.probeType !== PROBE_REALTIME) { this.trigger('scrollEnd', { x: this.x, y: this.y }); } } }; BScroll.prototype._translate = function (x, y, scale) { assert(!isUndef(x) && !isUndef(y), 'Translate x or y is null or undefined.'); if (isUndef(scale)) { scale = this.scale; } if (this.options.useTransform) { this.scrollerStyle[style.transform] = 'translate(' + x + 'px,' + y + 'px) scale(' + scale + ')' + this.translateZ; } else { x = Math.round(x); y = Math.round(y); this.scrollerStyle.left = x + 'px'; this.scrollerStyle.top = y + 'px'; } if (this.options.wheel) { var _options$wheel$rotate = this.options.wheel.rotate, rotate = _options$wheel$rotate === undefined ? 25 : _options$wheel$rotate; for (var i = 0; i < this.items.length; i++) { var deg = rotate * (y / this.itemHeight + i); this.items[i].style[style.transform] = 'rotateX(' + deg + 'deg)'; } } this.x = x; this.y = y; this.setScale(scale); if (this.indicators) { for (var _i3 = 0; _i3 < this.indicators.length; _i3++) { this.indicators[_i3].updatePosition(); } } }; BScroll.prototype._animate = function (destX, destY, duration, easingFn) { var me = this; var startX = this.x; var startY = this.y; var startScale = this.lastScale; var destScale = this.scale; var startTime = getNow(); var destTime = startTime + duration; function step() { var now = getNow(); if (now >= destTime) { me.isAnimating = false; me._translate(destX, destY, destScale); me.trigger('scroll', { x: me.x, y: me.y }); if (!me.pulling && !me.resetPosition(me.options.bounceTime)) { me.trigger('scrollEnd', { x: me.x, y: me.y }); } return; } now = (now - startTime) / duration; var easing = easingFn(now); var newX = (destX - startX) * easing + startX; var newY = (destY - startY) * easing + startY; var newScale = (destScale - startScale) * easing + startScale; me._translate(newX, newY, newScale); if (me.isAnimating) { me.animateTimer = requestAnimationFrame(step); } if (me.options.probeType === PROBE_REALTIME) { me.trigger('scroll', { x: me.x, y: me.y }); } } this.isAnimating = true; cancelAnimationFrame(this.animateTimer); step(); }; BScroll.prototype.scrollBy = function (x, y) { var time = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; var easing = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ease.bounce; x = this.x + x; y = this.y + y; this.scrollTo(x, y, time, easing); }; BScroll.prototype.scrollTo = function (x, y) { var time = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; var easing = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ease.bounce; this.isInTransition = this.options.useTransition && time > 0 && (x !== this.x || y !== this.y); if (!time || this.options.useTransition) { this._transitionTimingFunction(easing.style); this._transitionTime(time); this._translate(x, y); if (time && this.options.probeType === PROBE_REALTIME) { this._startProbe(); } if (!time && (x !== this.x || y !== this.y)) { this.trigger('scroll', { x: x, y: y }); // force reflow to put everything in position this._reflow = document.body.offsetHeight; if (!this.resetPosition(this.options.bounceTime, ease.bounce)) { this.trigger('scrollEnd', { x: x, y: y }); } } if (this.options.wheel) { if (y > this.minScrollY) { this.selectedIndex = 0; } else if (y < this.maxScrollY) { this.selectedIndex = this.items.length - 1; } else { this.selectedIndex = Math.round(Math.abs(y / this.itemHeight)); } } } else { this._animate(x, y, time, easing.fn); } }; BScroll.prototype.scrollToElement = function (el, time, offsetX, offsetY, easing) { if (!el) { return; } el = el.nodeType ? el : this.scroller.querySelector(el); if (this.options.wheel && !el.classList.contains(this.options.wheel.wheelItemClass)) { return; } var pos = offset(el); pos.left -= this.wrapperOffset.left; pos.top -= this.wrapperOffset.top; // if offsetX/Y are true we center the element to the screen if (offsetX === true) { offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2); } if (offsetY === true) { offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2); } pos.left -= offsetX || 0; pos.top -= offsetY || 0; pos.left = pos.left > this.minScrollX ? this.minScrollX : pos.left < this.maxScrollX ? this.maxScrollX : pos.left; pos.top = pos.top > this.minScrollY ? this.minScrollY : pos.top < this.maxScrollY ? this.maxScrollY : pos.top; if (this.options.wheel) { pos.top = Math.round(pos.top / this.itemHeight) * this.itemHeight; } this.scrollTo(pos.left, pos.top, time, easing); }; BScroll.prototype.resetPosition = function () { var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var easeing = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ease.bounce; var x = this.x; var roundX = Math.round(x); if (!this.hasHorizontalScroll || roundX > this.minScrollX) { x = this.minScrollX; } else if (roundX < this.maxScrollX) { x = this.maxScrollX; } var y = this.y; var roundY = Math.round(y); if (!this.hasVerticalScroll || roundY > this.minScrollY) { y = this.minScrollY; } else if (roundY < this.maxScrollY) { y = this.maxScrollY; } if (x === this.x && y === this.y) { return false; } this.scrollTo(x, y, time, easeing); return true; }; BScroll.prototype.getComputedPosition = function () { var matrix = window.getComputedStyle(this.scroller, null); var x = void 0; var y = void 0; if (this.options.useTransform) { matrix = matrix[style.transform].split(')')[0].split(', '); x = +(matrix[12] || matrix[4]); y = +(matrix[13] || matrix[5]); } else { x = +matrix.left.replace(/[^-\d.]/g, ''); y = +matrix.top.replace(/[^-\d.]/g, ''); } return { x: x, y: y }; }; BScroll.prototype.stop = function () { if (this.options.useTransition && this.isInTransition) { this.isInTransition = false; cancelAnimationFrame(this.probeTimer); var pos = this.getComputedPosition(); this._translate(pos.x, pos.y); if (this.options.wheel) { this.target = this.items[Math.round(-pos.y / this.itemHeight)]; } else { this.trigger('scrollEnd', { x: this.x, y: this.y }); } this.stopFromTransition = true; } else if (!this.options.useTransition && this.isAnimating) { this.isAnimating = false; cancelAnimationFrame(this.animateTimer); this.trigger('scrollEnd', { x: this.x, y: this.y }); this.stopFromTransition = true; } }; BScroll.prototype.destroy = fun