123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667 |
- ! function(window, document, Math) {
- function IScroll(el, options) {
- this.wrapper = "string" == typeof el ? document.querySelector(el) : el, this.scroller = this.wrapper.children[0], this.scrollerStyle = this.scroller.style, this.options = {
- resizeScrollbars: !0,
- mouseWheelSpeed: 20,
- snapThreshold: .334,
- startX: 0,
- startY: 0,
- scrollY: !0,
- directionLockThreshold: 5,
- momentum: !0,
- bounce: !0,
- bounceTime: 600,
- bounceEasing: "",
- preventDefault: !0,
- preventDefaultException: {
- tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/
- },
- HWCompositing: !0,
- useTransition: !0,
- useTransform: !0
- };
- for (var i in options) this.options[i] = options[i];
- this.translateZ = this.options.HWCompositing && utils.hasPerspective ? " translateZ(0)" : "", this.options.useTransition = utils.hasTransition && this.options.useTransition, this.options.useTransform = utils.hasTransform && this.options.useTransform, this.options.eventPassthrough = this.options.eventPassthrough === !0 ? "vertical" : this.options.eventPassthrough, this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault, this.options.scrollY = "vertical" == this.options.eventPassthrough ? !1 : this.options.scrollY, this.options.scrollX = "horizontal" == this.options.eventPassthrough ? !1 : this.options.scrollX, this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough, this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold, this.options.bounceEasing = "string" == typeof this.options.bounceEasing ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing, this.options.resizePolling = void 0 === this.options.resizePolling ? 60 : this.options.resizePolling, this.options.tap === !0 && (this.options.tap = "tap"), "scale" == this.options.shrinkScrollbars && (this.options.useTransition = !1), this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1, this.x = 0, this.y = 0, this.directionX = 0, this.directionY = 0, this._events = {}, this._init(), this.refresh(), this.scrollTo(this.options.startX, this.options.startY), this.enable()
- }
- function createDefaultScrollbar(direction, interactive, type) {
- var scrollbar = document.createElement("div"),
- indicator = document.createElement("div");
- return type === !0 && (scrollbar.style.cssText = "position:absolute;z-index:9999", indicator.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);border-radius:3px"), indicator.className = "iScrollIndicator", "h" == direction ? (type === !0 && (scrollbar.style.cssText += ";height:7px;left:2px;right:2px;bottom:0", indicator.style.height = "100%"), scrollbar.className = "iScrollHorizontalScrollbar") : (type === !0 && (scrollbar.style.cssText += ";width:7px;bottom:2px;top:2px;right:1px", indicator.style.width = "100%"), scrollbar.className = "iScrollVerticalScrollbar"), scrollbar.style.cssText += ";overflow:hidden", interactive || (scrollbar.style.pointerEvents = "none"), scrollbar.appendChild(indicator), scrollbar
- }
- function Indicator(scroller, options) {
- this.wrapper = "string" == typeof options.el ? document.querySelector(options.el) : options.el, this.wrapperStyle = this.wrapper.style, this.indicator = this.wrapper.children[0], this.indicatorStyle = this.indicator.style, this.scroller = scroller, this.options = {
- listenX: !0,
- listenY: !0,
- interactive: !1,
- resize: !0,
- defaultScrollbars: !1,
- shrink: !1,
- fade: !1,
- speedRatioX: 0,
- speedRatioY: 0
- };
- for (var i in options) this.options[i] = options[i];
- this.sizeRatioX = 1, this.sizeRatioY = 1, this.maxPosX = 0, this.maxPosY = 0, this.options.interactive && (this.options.disableTouch || (utils.addEvent(this.indicator, "touchstart", this), utils.addEvent(window, "touchend", this)), this.options.disablePointer || (utils.addEvent(this.indicator, utils.prefixPointerEvent("pointerdown"), this), utils.addEvent(window, utils.prefixPointerEvent("pointerup"), this)), this.options.disableMouse || (utils.addEvent(this.indicator, "mousedown", this), utils.addEvent(window, "mouseup", this))), this.options.fade && (this.wrapperStyle[utils.style.transform] = this.scroller.translateZ, this.wrapperStyle[utils.style.transitionDuration] = utils.isBadAndroid ? "0.001s" : "0ms", this.wrapperStyle.opacity = "0")
- }
- var rAF = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
- window.setTimeout(callback, 1e3 / 60)
- },
- utils = function() {
- function _prefixStyle(style) {
- return _vendor === !1 ? !1 : "" === _vendor ? style : _vendor + style.charAt(0).toUpperCase() + style.substr(1)
- }
- var me = {},
- _elementStyle = document.createElement("div").style,
- _vendor = function() {
- for (var transform, vendors = ["t", "webkitT", "MozT", "msT", "OT"], i = 0, l = vendors.length; l > i; i++)
- if (transform = vendors[i] + "ransform", transform in _elementStyle) return vendors[i].substr(0, vendors[i].length - 1);
- return !1
- }();
- me.getTime = Date.now || function() {
- return (new Date).getTime()
- }, me.extend = function(target, obj) {
- for (var i in obj) target[i] = obj[i]
- }, me.addEvent = function(el, type, fn, capture) {
- el.addEventListener(type, fn, !!capture)
- }, me.removeEvent = function(el, type, fn, capture) {
- el.removeEventListener(type, fn, !!capture)
- }, me.prefixPointerEvent = function(pointerEvent) {
- return window.MSPointerEvent ? "MSPointer" + pointerEvent.charAt(9).toUpperCase() + pointerEvent.substr(10) : pointerEvent
- }, me.momentum = function(current, start, time, lowerMargin, wrapperSize, deceleration) {
- var destination, duration, distance = current - start,
- speed = Math.abs(distance) / time;
- return deceleration = void 0 === deceleration ? 6e-4 : deceleration, destination = current + speed * speed / (2 * deceleration) * (0 > distance ? -1 : 1), duration = speed / deceleration, lowerMargin > destination ? (destination = wrapperSize ? lowerMargin - wrapperSize / 2.5 * (speed / 8) : lowerMargin, distance = Math.abs(destination - current), duration = distance / speed) : destination > 0 && (destination = wrapperSize ? wrapperSize / 2.5 * (speed / 8) : 0, distance = Math.abs(current) + destination, duration = distance / speed), {
- destination: Math.round(destination),
- duration: duration
- }
- };
- var _transform = _prefixStyle("transform");
- return me.extend(me, {
- hasTransform: _transform !== !1,
- hasPerspective: _prefixStyle("perspective") in _elementStyle,
- hasTouch: "ontouchstart" in window,
- hasPointer: window.PointerEvent || window.MSPointerEvent,
- hasTransition: _prefixStyle("transition") in _elementStyle
- }), me.isBadAndroid = /Android /.test(window.navigator.appVersion) && !/Chrome\/\d/.test(window.navigator.appVersion), me.extend(me.style = {}, {
- transform: _transform,
- transitionTimingFunction: _prefixStyle("transitionTimingFunction"),
- transitionDuration: _prefixStyle("transitionDuration"),
- transitionDelay: _prefixStyle("transitionDelay"),
- transformOrigin: _prefixStyle("transformOrigin")
- }), me.hasClass = function(e, c) {
- var re = new RegExp("(^|\\s)" + c + "(\\s|$)");
- return re.test(e.className)
- }, me.addClass = function(e, c) {
- if (!me.hasClass(e, c)) {
- var newclass = e.className.split(" ");
- newclass.push(c), e.className = newclass.join(" ")
- }
- }, me.removeClass = function(e, c) {
- if (me.hasClass(e, c)) {
- var re = new RegExp("(^|\\s)" + c + "(\\s|$)", "g");
- e.className = e.className.replace(re, " ")
- }
- }, me.offset = function(el) {
- for (var left = -el.offsetLeft, top = -el.offsetTop; el = el.offsetParent;) left -= el.offsetLeft, top -= el.offsetTop;
- return {
- left: left,
- top: top
- }
- }, me.preventDefaultException = function(el, exceptions) {
- for (var i in exceptions)
- if (exceptions[i].test(el[i])) return !0;
- return !1
- }, me.extend(me.eventType = {}, {
- touchstart: 1,
- touchmove: 1,
- touchend: 1,
- mousedown: 2,
- mousemove: 2,
- mouseup: 2,
- pointerdown: 3,
- pointermove: 3,
- pointerup: 3,
- MSPointerDown: 3,
- MSPointerMove: 3,
- MSPointerUp: 3
- }), me.extend(me.ease = {}, {
- quadratic: {
- style: "cubic-bezier(0.25, 0.46, 0.45, 0.94)",
- fn: function(k) {
- return k * (2 - k)
- }
- },
- circular: {
- style: "cubic-bezier(0.1, 0.57, 0.1, 1)",
- fn: function(k) {
- return Math.sqrt(1 - --k * k)
- }
- },
- back: {
- style: "cubic-bezier(0.175, 0.885, 0.32, 1.275)",
- fn: function(k) {
- var b = 4;
- return (k -= 1) * k * ((b + 1) * k + b) + 1
- }
- },
- bounce: {
- style: "",
- fn: function(k) {
- return (k /= 1) < 1 / 2.75 ? 7.5625 * k * k : 2 / 2.75 > k ? 7.5625 * (k -= 1.5 / 2.75) * k + .75 : 2.5 / 2.75 > k ? 7.5625 * (k -= 2.25 / 2.75) * k + .9375 : 7.5625 * (k -= 2.625 / 2.75) * k + .984375
- }
- },
- elastic: {
- style: "",
- fn: function(k) {
- var f = .22,
- e = .4;
- return 0 === k ? 0 : 1 == k ? 1 : e * Math.pow(2, -10 * k) * Math.sin(2 * (k - f / 4) * Math.PI / f) + 1
- }
- }
- }), me.tap = function(e, eventName) {
- var ev = document.createEvent("Event");
- ev.initEvent(eventName, !0, !0), ev.pageX = e.pageX, ev.pageY = e.pageY, e.target.dispatchEvent(ev)
- }, me.click = function(e) {
- var ev, target = e.target;
- /(SELECT|INPUT|TEXTAREA)/i.test(target.tagName) || (ev = document.createEvent("MouseEvents"), ev.initMouseEvent("click", !0, !0, e.view, 1, target.screenX, target.screenY, target.clientX, target.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, 0, null), ev._constructed = !0, target.dispatchEvent(ev))
- }, me
- }();
- IScroll.prototype = {
- version: "5.1.2",
- _init: function() {
- this._initEvents(), (this.options.scrollbars || this.options.indicators) && this._initIndicators(), this.options.mouseWheel && this._initWheel(), this.options.snap && this._initSnap(), this.options.keyBindings && this._initKeys()
- },
- destroy: function() {
- this._initEvents(!0), this._execEvent("destroy")
- },
- _transitionEnd: function(e) {
- e.target == this.scroller && this.isInTransition && (this._transitionTime(), this.resetPosition(this.options.bounceTime) || (this.isInTransition = !1, this._execEvent("scrollEnd")))
- },
- _start: function(e) {
- if (!(1 != utils.eventType[e.type] && 0 !== e.button || !this.enabled || this.initiated && utils.eventType[e.type] !== this.initiated)) {
- !this.options.preventDefault || utils.isBadAndroid || utils.preventDefaultException(e.target, this.options.preventDefaultException) || e.preventDefault();
- var pos, point = e.touches ? e.touches[0] : e;
- this.initiated = utils.eventType[e.type], this.moved = !1, this.distX = 0, this.distY = 0, this.directionX = 0, this.directionY = 0, this.directionLocked = 0, this._transitionTime(), this.startTime = utils.getTime(), this.options.useTransition && this.isInTransition ? (this.isInTransition = !1, pos = this.getComputedPosition(), this._translate(Math.round(pos.x), Math.round(pos.y)), this._execEvent("scrollEnd")) : !this.options.useTransition && this.isAnimating && (this.isAnimating = !1, this._execEvent("scrollEnd")), 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._execEvent("beforeScrollStart")
- }
- },
- _move: function(e) {
- if (this.enabled && utils.eventType[e.type] === this.initiated) {
- this.options.preventDefault && e.preventDefault();
- var newX, newY, absDistX, absDistY, point = e.touches ? e.touches[0] : e,
- deltaX = point.pageX - this.pointX,
- deltaY = point.pageY - this.pointY,
- timestamp = utils.getTime();
- if (this.pointX = point.pageX, this.pointY = point.pageY, this.distX += deltaX, this.distY += deltaY, absDistX = Math.abs(this.distX), absDistY = Math.abs(this.distY), !(timestamp - this.endTime > 300 && 10 > absDistX && 10 > absDistY)) {
- if (this.directionLocked || this.options.freeScroll || (this.directionLocked = absDistX > absDistY + this.options.directionLockThreshold ? "h" : absDistY >= absDistX + this.options.directionLockThreshold ? "v" : "n"), "h" == this.directionLocked) {
- if ("vertical" == this.options.eventPassthrough) e.preventDefault();
- else if ("horizontal" == this.options.eventPassthrough) return void(this.initiated = !1);
- deltaY = 0
- } else if ("v" == this.directionLocked) {
- if ("horizontal" == this.options.eventPassthrough) e.preventDefault();
- else if ("vertical" == this.options.eventPassthrough) return void(this.initiated = !1);
- deltaX = 0
- }
- deltaX = this.hasHorizontalScroll ? deltaX : 0, deltaY = this.hasVerticalScroll ? deltaY : 0, newX = this.x + deltaX, newY = this.y + deltaY, (newX > 0 || newX < this.maxScrollX) && (newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX), (newY > 0 || newY < this.maxScrollY) && (newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY), this.directionX = deltaX > 0 ? -1 : 0 > deltaX ? 1 : 0, this.directionY = deltaY > 0 ? -1 : 0 > deltaY ? 1 : 0, this.moved || this._execEvent("scrollStart"), this.moved = !0, this._translate(newX, newY), timestamp - this.startTime > 300 && (this.startTime = timestamp, this.startX = this.x, this.startY = this.y)
- }
- }
- },
- _end: function(e) {
- if (this.enabled && utils.eventType[e.type] === this.initiated) {
- this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) && e.preventDefault();
- var momentumX, momentumY, duration = (e.changedTouches ? e.changedTouches[0] : e, utils.getTime() - this.startTime),
- newX = Math.round(this.x),
- newY = Math.round(this.y),
- distanceX = Math.abs(newX - this.startX),
- distanceY = Math.abs(newY - this.startY),
- time = 0,
- easing = "";
- if (this.isInTransition = 0, this.initiated = 0, this.endTime = utils.getTime(), !this.resetPosition(this.options.bounceTime)) {
- if (this.scrollTo(newX, newY), !this.moved) return this.options.tap && utils.tap(e, this.options.tap), this.options.click && utils.click(e), void this._execEvent("scrollCancel");
- if (this._events.flick && 200 > duration && 100 > distanceX && 100 > distanceY) return void this._execEvent("flick");
- if (this.options.momentum && 300 > duration && (momentumX = this.hasHorizontalScroll ? utils.momentum(this.x, this.startX, duration, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : {
- destination: newX,
- duration: 0
- }, momentumY = this.hasVerticalScroll ? utils.momentum(this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : {
- destination: newY,
- duration: 0
- }, newX = momentumX.destination, newY = momentumY.destination, time = Math.max(momentumX.duration, momentumY.duration), this.isInTransition = 1), 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), 1e3), Math.min(Math.abs(newY - snap.y), 1e3)), 300), newX = snap.x, newY = snap.y, this.directionX = 0, this.directionY = 0, easing = this.options.bounceEasing
- }
- return newX != this.x || newY != this.y ? ((newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY) && (easing = utils.ease.quadratic), void this.scrollTo(newX, newY, time, easing)) : void this._execEvent("scrollEnd")
- }
- }
- },
- _resize: function() {
- var that = this;
- clearTimeout(this.resizeTimeout), this.resizeTimeout = setTimeout(function() {
- that.refresh()
- }, this.options.resizePolling)
- },
- resetPosition: function(time) {
- var x = this.x,
- y = this.y;
- return time = time || 0, !this.hasHorizontalScroll || this.x > 0 ? x = 0 : this.x < this.maxScrollX && (x = this.maxScrollX), !this.hasVerticalScroll || this.y > 0 ? y = 0 : this.y < this.maxScrollY && (y = this.maxScrollY), x == this.x && y == this.y ? !1 : (this.scrollTo(x, y, time, this.options.bounceEasing), !0)
- },
- disable: function() {
- this.enabled = !1
- },
- enable: function() {
- this.enabled = !0
- },
- refresh: function() {
- this.wrapper.offsetHeight;
- this.wrapperWidth = this.wrapper.clientWidth, this.wrapperHeight = this.wrapper.clientHeight, this.scrollerWidth = this.scroller.offsetWidth, this.scrollerHeight = this.scroller.offsetHeight, this.maxScrollX = this.wrapperWidth - this.scrollerWidth, this.maxScrollY = this.wrapperHeight - this.scrollerHeight, this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0, this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0, this.hasHorizontalScroll || (this.maxScrollX = 0, this.scrollerWidth = this.wrapperWidth), this.hasVerticalScroll || (this.maxScrollY = 0, this.scrollerHeight = this.wrapperHeight), this.endTime = 0, this.directionX = 0, this.directionY = 0, this.wrapperOffset = utils.offset(this.wrapper), this._execEvent("refresh"), this.resetPosition()
- },
- on: function(type, fn) {
- this._events[type] || (this._events[type] = []), this._events[type].push(fn)
- },
- off: function(type, fn) {
- if (this._events[type]) {
- var index = this._events[type].indexOf(fn);
- index > -1 && this._events[type].splice(index, 1)
- }
- },
- _execEvent: function(type) {
- if (this._events[type]) {
- var i = 0,
- l = this._events[type].length;
- if (l)
- for (; l > i; i++) this._events[type][i].apply(this, [].slice.call(arguments, 1))
- }
- },
- scrollBy: function(x, y, time, easing) {
- x = this.x + x, y = this.y + y, time = time || 0, this.scrollTo(x, y, time, easing)
- },
- scrollTo: function(x, y, time, easing) {
- easing = easing || utils.ease.circular, this.isInTransition = this.options.useTransition && time > 0, !time || this.options.useTransition && easing.style ? (this._transitionTimingFunction(easing.style), this._transitionTime(time), this._translate(x, y)) : this._animate(x, y, time, easing.fn)
- },
- scrollToElement: function(el, time, offsetX, offsetY, easing) {
- if (el = el.nodeType ? el : this.scroller.querySelector(el)) {
- var pos = utils.offset(el);
- pos.left -= this.wrapperOffset.left, pos.top -= this.wrapperOffset.top, offsetX === !0 && (offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2)), offsetY === !0 && (offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2)), pos.left -= offsetX || 0, pos.top -= offsetY || 0, pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left, pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top, time = void 0 === time || null === time || "auto" === time ? Math.max(Math.abs(this.x - pos.left), Math.abs(this.y - pos.top)) : time, this.scrollTo(pos.left, pos.top, time, easing)
- }
- },
- _transitionTime: function(time) {
- if (time = time || 0, this.scrollerStyle[utils.style.transitionDuration] = time + "ms", !time && utils.isBadAndroid && (this.scrollerStyle[utils.style.transitionDuration] = "0.001s"), this.indicators)
- for (var i = this.indicators.length; i--;) this.indicators[i].transitionTime(time)
- },
- _transitionTimingFunction: function(easing) {
- if (this.scrollerStyle[utils.style.transitionTimingFunction] = easing, this.indicators)
- for (var i = this.indicators.length; i--;) this.indicators[i].transitionTimingFunction(easing)
- },
- _translate: function(x, y) {
- if (this.options.useTransform ? this.scrollerStyle[utils.style.transform] = "translate(" + x + "px," + y + "px)" + this.translateZ : (x = Math.round(x), y = Math.round(y), this.scrollerStyle.left = x + "px", this.scrollerStyle.top = y + "px"), this.x = x, this.y = y, this.indicators)
- for (var i = this.indicators.length; i--;) this.indicators[i].updatePosition()
- },
- _initEvents: function(remove) {
- var eventType = remove ? utils.removeEvent : utils.addEvent,
- target = this.options.bindToWrapper ? this.wrapper : window;
- eventType(window, "orientationchange", this), eventType(window, "resize", this), this.options.click && eventType(this.wrapper, "click", this, !0), this.options.disableMouse || (eventType(this.wrapper, "mousedown", this), eventType(target, "mousemove", this), eventType(target, "mousecancel", this), eventType(target, "mouseup", this)), utils.hasPointer && !this.options.disablePointer && (eventType(this.wrapper, utils.prefixPointerEvent("pointerdown"), this), eventType(target, utils.prefixPointerEvent("pointermove"), this), eventType(target, utils.prefixPointerEvent("pointercancel"), this), eventType(target, utils.prefixPointerEvent("pointerup"), this)), utils.hasTouch && !this.options.disableTouch && (eventType(this.wrapper, "touchstart", this), eventType(target, "touchmove", this), eventType(target, "touchcancel", this), eventType(target, "touchend", this)), eventType(this.scroller, "transitionend", this), eventType(this.scroller, "webkitTransitionEnd", this), eventType(this.scroller, "oTransitionEnd", this), eventType(this.scroller, "MSTransitionEnd", this)
- },
- getComputedPosition: function() {
- var x, y, matrix = window.getComputedStyle(this.scroller, null);
- return this.options.useTransform ? (matrix = matrix[utils.style.transform].split(")")[0].split(", "), x = +(matrix[12] || matrix[4]), y = +(matrix[13] || matrix[5])) : (x = +matrix.left.replace(/[^-\d.]/g, ""), y = +matrix.top.replace(/[^-\d.]/g, "")), {
- x: x,
- y: y
- }
- },
- _initIndicators: function() {
- function _indicatorsMap(fn) {
- for (var i = that.indicators.length; i--;) fn.call(that.indicators[i])
- }
- var indicator, interactive = this.options.interactiveScrollbars,
- customStyle = "string" != typeof this.options.scrollbars,
- indicators = [],
- that = this;
- this.indicators = [], this.options.scrollbars && (this.options.scrollY && (indicator = {
- el: createDefaultScrollbar("v", interactive, this.options.scrollbars),
- interactive: interactive,
- defaultScrollbars: !0,
- customStyle: customStyle,
- resize: this.options.resizeScrollbars,
- shrink: this.options.shrinkScrollbars,
- fade: this.options.fadeScrollbars,
- listenX: !1
- }, this.wrapper.appendChild(indicator.el), indicators.push(indicator)), this.options.scrollX && (indicator = {
- el: createDefaultScrollbar("h", interactive, this.options.scrollbars),
- interactive: interactive,
- defaultScrollbars: !0,
- customStyle: customStyle,
- resize: this.options.resizeScrollbars,
- shrink: this.options.shrinkScrollbars,
- fade: this.options.fadeScrollbars,
- listenY: !1
- }, this.wrapper.appendChild(indicator.el), indicators.push(indicator))), this.options.indicators && (indicators = indicators.concat(this.options.indicators));
- for (var i = indicators.length; i--;) this.indicators.push(new Indicator(this, indicators[i]));
- this.options.fadeScrollbars && (this.on("scrollEnd", function() {
- _indicatorsMap(function() {
- this.fade()
- })
- }), this.on("scrollCancel", function() {
- _indicatorsMap(function() {
- this.fade()
- })
- }), this.on("scrollStart", function() {
- _indicatorsMap(function() {
- this.fade(1)
- })
- }), this.on("beforeScrollStart", function() {
- _indicatorsMap(function() {
- this.fade(1, !0)
- })
- })), this.on("refresh", function() {
- _indicatorsMap(function() {
- this.refresh()
- })
- }), this.on("destroy", function() {
- _indicatorsMap(function() {
- this.destroy()
- }), delete this.indicators
- })
- },
- _initWheel: function() {
- utils.addEvent(this.wrapper, "wheel", this), utils.addEvent(this.wrapper, "mousewheel", this), utils.addEvent(this.wrapper, "DOMMouseScroll", this), this.on("destroy", function() {
- utils.removeEvent(this.wrapper, "wheel", this), utils.removeEvent(this.wrapper, "mousewheel", this), utils.removeEvent(this.wrapper, "DOMMouseScroll", this)
- })
- },
- _wheel: function(e) {
- if (this.enabled) {
- e.preventDefault(), e.stopPropagation();
- var wheelDeltaX, wheelDeltaY, newX, newY, that = this;
- if (void 0 === this.wheelTimeout && that._execEvent("scrollStart"), clearTimeout(this.wheelTimeout), this.wheelTimeout = setTimeout(function() {
- that._execEvent("scrollEnd"), that.wheelTimeout = void 0
- }, 400), "deltaX" in e) wheelDeltaX = -e.deltaX, wheelDeltaY = -e.deltaY;
- else if ("wheelDeltaX" in e) wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed, wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed;
- else if ("wheelDelta" in e) wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed;
- else {
- if (!("detail" in e)) return;
- wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed
- } if (wheelDeltaX *= this.options.invertWheelDirection, wheelDeltaY *= this.options.invertWheelDirection, this.hasVerticalScroll || (wheelDeltaX = wheelDeltaY, wheelDeltaY = 0), this.options.snap) return newX = this.currentPage.pageX, newY = this.currentPage.pageY, wheelDeltaX > 0 ? newX-- : 0 > wheelDeltaX && newX++, wheelDeltaY > 0 ? newY-- : 0 > wheelDeltaY && newY++, void this.goToPage(newX, newY);
- newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0), newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0), newX > 0 ? newX = 0 : newX < this.maxScrollX && (newX = this.maxScrollX), newY > 0 ? newY = 0 : newY < this.maxScrollY && (newY = this.maxScrollY), this.scrollTo(newX, newY, 0)
- }
- },
- _initSnap: function() {
- this.currentPage = {}, "string" == typeof this.options.snap && (this.options.snap = this.scroller.querySelectorAll(this.options.snap)), this.on("refresh", function() {
- var l, n, cx, cy, y, el, i = 0,
- m = 0,
- x = 0,
- stepX = this.options.snapStepX || this.wrapperWidth,
- stepY = this.options.snapStepY || this.wrapperHeight;
- if (this.pages = [], this.wrapperWidth && this.wrapperHeight && this.scrollerWidth && this.scrollerHeight) {
- if (this.options.snap === !0)
- for (cx = Math.round(stepX / 2), cy = Math.round(stepY / 2); x > -this.scrollerWidth;) {
- for (this.pages[i] = [], l = 0, y = 0; y > -this.scrollerHeight;) this.pages[i][l] = {
- x: Math.max(x, this.maxScrollX),
- y: Math.max(y, this.maxScrollY),
- width: stepX,
- height: stepY,
- cx: x - cx,
- cy: y - cy
- }, y -= stepY, l++;
- x -= stepX, i++
- } else
- for (el = this.options.snap, l = el.length, n = -1; l > i; i++)(0 === i || el[i].offsetLeft <= el[i - 1].offsetLeft) && (m = 0, n++), this.pages[m] || (this.pages[m] = []), x = Math.max(-el[i].offsetLeft, this.maxScrollX), y = Math.max(-el[i].offsetTop, this.maxScrollY), cx = x - Math.round(el[i].offsetWidth / 2), cy = y - Math.round(el[i].offsetHeight / 2), this.pages[m][n] = {
- x: x,
- y: y,
- width: el[i].offsetWidth,
- height: el[i].offsetHeight,
- cx: cx,
- cy: cy
- }, x > this.maxScrollX && m++;
- this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0), this.options.snapThreshold % 1 === 0 ? (this.snapThresholdX = this.options.snapThreshold, this.snapThresholdY = this.options.snapThreshold) : (this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold), this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold))
- }
- }), this.on("flick", function() {
- var time = this.options.snapSpeed || Math.max(Math.max(Math.min(Math.abs(this.x - this.startX), 1e3), Math.min(Math.abs(this.y - this.startY), 1e3)), 300);
- this.goToPage(this.currentPage.pageX + this.directionX, this.currentPage.pageY + this.directionY, time)
- })
- },
- _nearestSnap: function(x, y) {
- if (!this.pages.length) return {
- x: 0,
- y: 0,
- pageX: 0,
- pageY: 0
- };
- var i = 0,
- l = this.pages.length,
- m = 0;
- if (Math.abs(x - this.absStartX) < this.snapThresholdX && Math.abs(y - this.absStartY) < this.snapThresholdY) return this.currentPage;
- for (x > 0 ? x = 0 : x < this.maxScrollX && (x = this.maxScrollX), y > 0 ? y = 0 : y < this.maxScrollY && (y = this.maxScrollY); l > i; i++)
- if (x >= this.pages[i][0].cx) {
- x = this.pages[i][0].x;
- break
- }
- for (l = this.pages[i].length; l > m; m++)
- if (y >= this.pages[0][m].cy) {
- y = this.pages[0][m].y;
- break
- }
- return i == this.currentPage.pageX && (i += this.directionX, 0 > i ? i = 0 : i >= this.pages.length && (i = this.pages.length - 1), x = this.pages[i][0].x), m == this.currentPage.pageY && (m += this.directionY, 0 > m ? m = 0 : m >= this.pages[0].length && (m = this.pages[0].length - 1), y = this.pages[0][m].y), {
- x: x,
- y: y,
- pageX: i,
- pageY: m
- }
- },
- goToPage: function(x, y, time, easing) {
- easing = easing || this.options.bounceEasing, x >= this.pages.length ? x = this.pages.length - 1 : 0 > x && (x = 0), y >= this.pages[x].length ? y = this.pages[x].length - 1 : 0 > y && (y = 0);
- var posX = this.pages[x][y].x,
- posY = this.pages[x][y].y;
- time = void 0 === time ? this.options.snapSpeed || Math.max(Math.max(Math.min(Math.abs(posX - this.x), 1e3), Math.min(Math.abs(posY - this.y), 1e3)), 300) : time, this.currentPage = {
- x: posX,
- y: posY,
- pageX: x,
- pageY: y
- }, this.scrollTo(posX, posY, time, easing)
- },
- next: function(time, easing) {
- var x = this.currentPage.pageX,
- y = this.currentPage.pageY;
- x++, x >= this.pages.length && this.hasVerticalScroll && (x = 0, y++), this.goToPage(x, y, time, easing)
- },
- prev: function(time, easing) {
- var x = this.currentPage.pageX,
- y = this.currentPage.pageY;
- x--, 0 > x && this.hasVerticalScroll && (x = 0, y--), this.goToPage(x, y, time, easing)
- },
- _initKeys: function() {
- var i, keys = {
- pageUp: 33,
- pageDown: 34,
- end: 35,
- home: 36,
- left: 37,
- up: 38,
- right: 39,
- down: 40
- };
- if ("object" == typeof this.options.keyBindings)
- for (i in this.options.keyBindings) "string" == typeof this.options.keyBindings[i] && (this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCodeAt(0));
- else this.options.keyBindings = {};
- for (i in keys) this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i];
- utils.addEvent(window, "keydown", this), this.on("destroy", function() {
- utils.removeEvent(window, "keydown", this)
- })
- },
- _key: function(e) {
- if (this.enabled) {
- var pos, snap = this.options.snap,
- newX = snap ? this.currentPage.pageX : this.x,
- newY = snap ? this.currentPage.pageY : this.y,
- now = utils.getTime(),
- prevTime = this.keyTime || 0,
- acceleration = .25;
- switch (this.options.useTransition && this.isInTransition && (pos = this.getComputedPosition(), this._translate(Math.round(pos.x), Math.round(pos.y)), this.isInTransition = !1), this.keyAcceleration = 200 > now - prevTime ? Math.min(this.keyAcceleration + acceleration, 50) : 0, e.keyCode) {
- case this.options.keyBindings.pageUp:
- this.hasHorizontalScroll && !this.hasVerticalScroll ? newX += snap ? 1 : this.wrapperWidth : newY += snap ? 1 : this.wrapperHeight;
- break;
- case this.options.keyBindings.pageDown:
- this.hasHorizontalScroll && !this.hasVerticalScroll ? newX -= snap ? 1 : this.wrapperWidth : newY -= snap ? 1 : this.wrapperHeight;
- break;
- case this.options.keyBindings.end:
- newX = snap ? this.pages.length - 1 : this.maxScrollX, newY = snap ? this.pages[0].length - 1 : this.maxScrollY;
- break;
- case this.options.keyBindings.home:
- newX = 0, newY = 0;
- break;
- case this.options.keyBindings.left:
- newX += snap ? -1 : 5 + this.keyAcceleration >> 0;
- break;
- case this.options.keyBindings.up:
- newY += snap ? 1 : 5 + this.keyAcceleration >> 0;
- break;
- case this.options.keyBindings.right:
- newX -= snap ? -1 : 5 + this.keyAcceleration >> 0;
- break;
- case this.options.keyBindings.down:
- newY -= snap ? 1 : 5 + this.keyAcceleration >> 0;
- break;
- default:
- return
- }
- if (snap) return void this.goToPage(newX, newY);
- newX > 0 ? (newX = 0, this.keyAcceleration = 0) : newX < this.maxScrollX && (newX = this.maxScrollX, this.keyAcceleration = 0), newY > 0 ? (newY = 0, this.keyAcceleration = 0) : newY < this.maxScrollY && (newY = this.maxScrollY, this.keyAcceleration = 0), this.scrollTo(newX, newY, 0), this.keyTime = now
- }
- },
- _animate: function(destX, destY, duration, easingFn) {
- function step() {
- var newX, newY, easing, now = utils.getTime();
- return now >= destTime ? (that.isAnimating = !1, that._translate(destX, destY), void(that.resetPosition(that.options.bounceTime) || that._execEvent("scrollEnd"))) : (now = (now - startTime) / duration, easing = easingFn(now), newX = (destX - startX) * easing + startX, newY = (destY - startY) * easing + startY, that._translate(newX, newY), void(that.isAnimating && rAF(step)))
- }
- var that = this,
- startX = this.x,
- startY = this.y,
- startTime = utils.getTime(),
- destTime = startTime + duration;
- this.isAnimating = !0, step()
- },
- handleEvent: function(e) {
- switch (e.type) {
- case "touchstart":
- case "pointerdown":
- case "MSPointerDown":
- case "mousedown":
- this._start(e);
- break;
- case "touchmove":
- case "pointermove":
- case "MSPointerMove":
- case "mousemove":
- this._move(e);
- break;
- case "touchend":
- case "pointerup":
- case "MSPointerUp":
- case "mouseup":
- case "touchcancel":
- case "pointercancel":
- case "MSPointerCancel":
- case "mousecancel":
- this._end(e);
- break;
- case "orientationchange":
- case "resize":
- this._resize();
- break;
- case "transitionend":
- case "webkitTransitionEnd":
- case "oTransitionEnd":
- case "MSTransitionEnd":
- this._transitionEnd(e);
- break;
- case "wheel":
- case "DOMMouseScroll":
- case "mousewheel":
- this._wheel(e);
- break;
- case "keydown":
- this._key(e);
- break;
- case "click":
- e._constructed || (e.preventDefault(), e.stopPropagation())
- }
- }
- }, Indicator.prototype = {
- handleEvent: function(e) {
- switch (e.type) {
- case "touchstart":
- case "pointerdown":
- case "MSPointerDown":
- case "mousedown":
- this._start(e);
- break;
- case "touchmove":
- case "pointermove":
- case "MSPointerMove":
- case "mousemove":
- this._move(e);
- break;
- case "touchend":
- case "pointerup":
- case "MSPointerUp":
- case "mouseup":
- case "touchcancel":
- case "pointercancel":
- case "MSPointerCancel":
- case "mousecancel":
- this._end(e)
- }
- },
- destroy: function() {
- this.options.interactive && (utils.removeEvent(this.indicator, "touchstart", this), utils.removeEvent(this.indicator, utils.prefixPointerEvent("pointerdown"), this), utils.removeEvent(this.indicator, "mousedown", this), utils.removeEvent(window, "touchmove", this), utils.removeEvent(window, utils.prefixPointerEvent("pointermove"), this), utils.removeEvent(window, "mousemove", this), utils.removeEvent(window, "touchend", this), utils.removeEvent(window, utils.prefixPointerEvent("pointerup"), this), utils.removeEvent(window, "mouseup", this)), this.options.defaultScrollbars && this.wrapper.parentNode.removeChild(this.wrapper)
- },
- _start: function(e) {
- var point = e.touches ? e.touches[0] : e;
- e.preventDefault(), e.stopPropagation(), this.transitionTime(), this.initiated = !0, this.moved = !1, this.lastPointX = point.pageX, this.lastPointY = point.pageY, this.startTime = utils.getTime(), this.options.disableTouch || utils.addEvent(window, "touchmove", this), this.options.disablePointer || utils.addEvent(window, utils.prefixPointerEvent("pointermove"), this), this.options.disableMouse || utils.addEvent(window, "mousemove", this), this.scroller._execEvent("beforeScrollStart")
- },
- _move: function(e) {
- {
- var deltaX, deltaY, newX, newY, point = e.touches ? e.touches[0] : e;
- utils.getTime()
- }
- this.moved || this.scroller._execEvent("scrollStart"), this.moved = !0, deltaX = point.pageX - this.lastPointX, this.lastPointX = point.pageX, deltaY = point.pageY - this.lastPointY, this.lastPointY = point.pageY, newX = this.x + deltaX, newY = this.y + deltaY, this._pos(newX, newY), e.preventDefault(), e.stopPropagation()
- },
- _end: function(e) {
- if (this.initiated) {
- if (this.initiated = !1, e.preventDefault(), e.stopPropagation(), utils.removeEvent(window, "touchmove", this), utils.removeEvent(window, utils.prefixPointerEvent("pointermove"), this), utils.removeEvent(window, "mousemove", this), this.scroller.options.snap) {
- var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y),
- time = this.options.snapSpeed || Math.max(Math.max(Math.min(Math.abs(this.scroller.x - snap.x), 1e3), Math.min(Math.abs(this.scroller.y - snap.y), 1e3)), 300);
- (this.scroller.x != snap.x || this.scroller.y != snap.y) && (this.scroller.directionX = 0, this.scroller.directionY = 0, this.scroller.currentPage = snap, this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing))
- }
- this.moved && this.scroller._execEvent("scrollEnd")
- }
- },
- transitionTime: function(time) {
- time = time || 0, this.indicatorStyle[utils.style.transitionDuration] = time + "ms", !time && utils.isBadAndroid && (this.indicatorStyle[utils.style.transitionDuration] = "0.001s")
- },
- transitionTimingFunction: function(easing) {
- this.indicatorStyle[utils.style.transitionTimingFunction] = easing
- },
- refresh: function() {
- this.transitionTime(), this.indicatorStyle.display = this.options.listenX && !this.options.listenY ? this.scroller.hasHorizontalScroll ? "block" : "none" : this.options.listenY && !this.options.listenX ? this.scroller.hasVerticalScroll ? "block" : "none" : this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? "block" : "none", this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ? (utils.addClass(this.wrapper, "iScrollBothScrollbars"), utils.removeClass(this.wrapper, "iScrollLoneScrollbar"), this.options.defaultScrollbars && this.options.customStyle && (this.options.listenX ? this.wrapper.style.right = "8px" : this.wrapper.style.bottom = "8px")) : (utils.removeClass(this.wrapper, "iScrollBothScrollbars"), utils.addClass(this.wrapper, "iScrollLoneScrollbar"), this.options.defaultScrollbars && this.options.customStyle && (this.options.listenX ? this.wrapper.style.right = "2px" : this.wrapper.style.bottom = "2px"));
- this.wrapper.offsetHeight;
- this.options.listenX && (this.wrapperWidth = this.wrapper.clientWidth, this.options.resize ? (this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8), this.indicatorStyle.width = this.indicatorWidth + "px") : this.indicatorWidth = this.indicator.clientWidth, this.maxPosX = this.wrapperWidth - this.indicatorWidth, "clip" == this.options.shrink ? (this.minBoundaryX = -this.indicatorWidth + 8, this.maxBoundaryX = this.wrapperWidth - 8) : (this.minBoundaryX = 0, this.maxBoundaryX = this.maxPosX), this.sizeRatioX = this.options.speedRatioX || this.scroller.maxScrollX && this.maxPosX / this.scroller.maxScrollX), this.options.listenY && (this.wrapperHeight = this.wrapper.clientHeight, this.options.resize ? (this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8), this.indicatorStyle.height = this.indicatorHeight + "px") : this.indicatorHeight = this.indicator.clientHeight, this.maxPosY = this.wrapperHeight - this.indicatorHeight, "clip" == this.options.shrink ? (this.minBoundaryY = -this.indicatorHeight + 8, this.maxBoundaryY = this.wrapperHeight - 8) : (this.minBoundaryY = 0, this.maxBoundaryY = this.maxPosY), this.maxPosY = this.wrapperHeight - this.indicatorHeight, this.sizeRatioY = this.options.speedRatioY || this.scroller.maxScrollY && this.maxPosY / this.scroller.maxScrollY), this.updatePosition()
- },
- updatePosition: function() {
- var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0,
- y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0;
- this.options.ignoreBoundaries || (x < this.minBoundaryX ? ("scale" == this.options.shrink && (this.width = Math.max(this.indicatorWidth + x, 8), this.indicatorStyle.width = this.width + "px"), x = this.minBoundaryX) : x > this.maxBoundaryX ? "scale" == this.options.shrink ? (this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8), this.indicatorStyle.width = this.width + "px", x = this.maxPosX + this.indicatorWidth - this.width) : x = this.maxBoundaryX : "scale" == this.options.shrink && this.width != this.indicatorWidth && (this.width = this.indicatorWidth, this.indicatorStyle.width = this.width + "px"), y < this.minBoundaryY ? ("scale" == this.options.shrink && (this.height = Math.max(this.indicatorHeight + 3 * y, 8), this.indicatorStyle.height = this.height + "px"), y = this.minBoundaryY) : y > this.maxBoundaryY ? "scale" == this.options.shrink ? (this.height = Math.max(this.indicatorHeight - 3 * (y - this.maxPosY), 8), this.indicatorStyle.height = this.height + "px", y = this.maxPosY + this.indicatorHeight - this.height) : y = this.maxBoundaryY : "scale" == this.options.shrink && this.height != this.indicatorHeight && (this.height = this.indicatorHeight, this.indicatorStyle.height = this.height + "px")), this.x = x, this.y = y, this.scroller.options.useTransform ? this.indicatorStyle[utils.style.transform] = "translate(" + x + "px," + y + "px)" + this.scroller.translateZ : (this.indicatorStyle.left = x + "px", this.indicatorStyle.top = y + "px")
- },
- _pos: function(x, y) {
- 0 > x ? x = 0 : x > this.maxPosX && (x = this.maxPosX), 0 > y ? y = 0 : y > this.maxPosY && (y = this.maxPosY), x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x, y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y, this.scroller.scrollTo(x, y)
- },
- fade: function(val, hold) {
- if (!hold || this.visible) {
- clearTimeout(this.fadeTimeout), this.fadeTimeout = null;
- var time = val ? 250 : 500,
- delay = val ? 0 : 300;
- val = val ? "1" : "0", this.wrapperStyle[utils.style.transitionDuration] = time + "ms", this.fadeTimeout = setTimeout(function(val) {
- this.wrapperStyle.opacity = val, this.visible = +val
- }.bind(this, val), delay)
- }
- }
- }, IScroll.utils = utils, qike.lib.IScroll = IScroll
- }(window, document, Math);
|