删减版iScroll
来源:互联网 发布:不动产数据库标准 编辑:程序博客网 时间:2024/06/11 22:52
删减版iScroll
在移动端想使用iScroll,奈何偏大,大的部分功能用不上,因此删减了部分代码,怕名称冲突,随便起了个名字Pan,其中防止重复调用,使用了xPath,贴上代码。
只是删了些东西,所以叫删减版,大部分功能保留。
define(function() { var instanceMap = {}; var utils = (function() { var me = {}; me.offset = function(el) { var left = -el.offsetLeft, top = -el.offsetTop; while (el = el.offsetParent) { left -= el.offsetLeft; top -= el.offsetTop; } return { left: left, top: top }; }; var _elementStyle = document.createElement('div').style; var _vendor = (function() { var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'], transform, i = 0, l = vendors.length; for (; i < l; i++) { transform = vendors[i] + 'ransform'; if (transform in _elementStyle) return vendors[i].substr(0, vendors[i].length - 1); } return false; })(); function _prefixStyle(style) { if (_vendor === false) return false; if (_vendor === '') return style; return _vendor + style.charAt(0).toUpperCase() + style.substr(1); } me.getTime = Date.now || function getTime() { 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.momentum = function(current, start, time, lowerMargin, wrapperSize, deceleration) { var distance = current - start, speed = Math.abs(distance) / time, destination, duration; deceleration = deceleration === undefined ? 0.0006 : deceleration; destination = current + (speed * speed) / (2 * deceleration) * (distance < 0 ? -1 : 1); duration = speed / deceleration; if (destination < lowerMargin) { destination = wrapperSize ? lowerMargin - (wrapperSize / 2.5 * (speed / 8)) : lowerMargin; distance = Math.abs(destination - current); duration = distance / speed; } else if (destination > 0) { destination = wrapperSize ? wrapperSize / 2.5 * (speed / 8) : 0; distance = Math.abs(current) + destination; duration = distance / speed; } return { destination: Math.round(destination), duration: duration }; }; var _transform = _prefixStyle('transform'); me.extend(me.style = {}, { transform: _transform, transitionTimingFunction: _prefixStyle('transitionTimingFunction'), transitionDuration: _prefixStyle('transitionDuration'), transitionDelay: _prefixStyle('transitionDelay'), transformOrigin: _prefixStyle('transformOrigin') }); me.preventDefaultException = function(el, exceptions) { for (var i in exceptions) { if (exceptions[i].test(el[i])) { return true; } } return false; }; me.extend(me.eventType = {}, { touchstart: 1, touchmove: 1, touchend: 1, }); 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 = k - 1) * k * ((b + 1) * k + b) + 1; } }, bounce: { style: '', fn: function(k) { if ((k /= 1) < (1 / 2.75)) { return 7.5625 * k * k; } else if (k < (2 / 2.75)) { return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75; } else if (k < (2.5 / 2.75)) { return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375; } else { return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375; } } }, elastic: { style: '', fn: function(k) { var f = 0.22, e = 0.4; if (k === 0) { return 0; } if (k == 1) { return 1; } return (e * Math.pow(2, -10 * k) * Math.sin((k - f / 4) * (2 * Math.PI) / f) + 1); } } }); me.click = function(e) { var target = e.target, ev; if (!(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName)) { ev = document.createEvent('MouseEvents'); ev.initMouseEvent('click', true, true, e.view, 1, target.screenX, target.screenY, target.clientX, target.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, 0, null); ev._constructed = true; target.dispatchEvent(ev); } }; return me; })(); function Pan(el, options) { this.wrapper = typeof el == 'string' ? document.querySelector(el) : el; var panId = this.wrapper.getAttribute("data-panid"); //判断实例是否已经存在,存在返回 if (panId && instanceMap[panId]) { var panInstance = instanceMap[panId]; if (panInstance.wrapper === this.wrapper) { return panInstance; } else { delete instanceMap[panId]; } } panId = utils.getTime(); this.wrapper.setAttribute("data-panid", panId); instanceMap[panId] = this; this.scroller = this.wrapper.children[0]; this.scrollerStyle = this.scroller.style; this.options = { startY: 0, momentum: true, bindToWrapper: true, bounce: true, bounceTime: 600, bounceEasing: '', preventDefault: true, preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/ }, }; for (var i in options) { this.options[i] = options[i]; } this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough; this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault; this.y = 0; this._events = {}; this._init(); this.refresh(); this.scrollTo(this.options.startY); this.enable(); } Pan.prototype = { _init: function() { this._initEvents(); }, destroy: function() { this._initEvents(true); }, _transitionEnd: function(e) { if (e.target != this.scroller || !this.isInTransition) { return; } this._transitionTime(); if (!this.resetPosition(this.options.bounceTime)) { this.isInTransition = false; } }, _start: function(e) { this.refresh(); if (!this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated)) { return; } if (this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException)) { e.preventDefault(); } var point = e.touches ? e.touches[0] : e, pos; this.initiated = utils.eventType[e.type]; this.moved = false; this.distY = 0; this._transitionTime(); this.startTime = utils.getTime(); if (this.options.useTransition && this.isInTransition) { this.isInTransition = false; pos = this.getComputedPosition(); this._translate(Math.round(pos.y)); } else if (!this.options.useTransition && this.isAnimating) { this.isAnimating = false; } this.startY = this.y; this.absStartY = this.y; this.pointY = point.pageY; }, _move: function(e) { if (!this.enabled || utils.eventType[e.type] !== this.initiated) { return; } if (this.options.preventDefault) { e.preventDefault(); } var point = e.touches ? e.touches[0] : e, deltaY = point.pageY - this.pointY, timestamp = utils.getTime(), newY, absDistY; this.pointY = point.pageY; this.distY += deltaY; absDistY = Math.abs(this.distY); if (timestamp - this.endTime > 300 && (absDistY < 10)) { return; } newY = this.y + deltaY; //newy >0 为超出上边界;newY < this.maxScrollY为超出下边界 if (newY > 0 || newY < this.maxScrollY) { newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; } this.moved = true; this._translate(newY); if (timestamp - this.startTime > 300) { this.startTime = timestamp; this.startY = this.y; } }, _end: function(e) { if (!this.enabled || utils.eventType[e.type] !== this.initiated) { return; } if (this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException)) { e.preventDefault(); } var point = e.changedTouches ? e.changedTouches[0] : e, momentumY, duration = utils.getTime() - this.startTime, newY = Math.round(this.y), distanceY = Math.abs(newY - this.startY), time = 0, easing = ''; this.isInTransition = 0; this.initiated = 0; this.endTime = utils.getTime(); //处理当滑动到边界时,回弹动作 if (this.resetPosition(this.options.bounceTime)) { return; } this.scrollTo(newY); //当touchend触发时,如果中间没有移动,则程序触发click事件到target上 if (!this.moved) { if (this.options.click) { utils.click(e); } return; } //当快速的滑动时,添加惯性效果(根据滑动的时间,已滑动的距离,保持当前的速度滑动一段距离才停下来) if (this.options.momentum && duration < 300) { momentumY = utils.momentum(this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration); newY = momentumY.destination; time = momentumY.duration; this.isInTransition = 1; } if (newY != this.y) { if (newY > 0 || newY < this.maxScrollY) { easing = utils.ease.quadratic; } this.scrollTo(newY, time, easing); return; } }, _resize: function() { var that = this; clearTimeout(this.resizeTimeout); this.resizeTimeout = setTimeout(function() { that.refresh(); }, this.options.resizePolling); }, resetPosition: function(time) { var y = this.y; time = time || 0; if (this.y > 0) { y = 0; } else if (this.y < this.maxScrollY) { y = this.maxScrollY; } if (y == this.y) { return false; } this.scrollTo(y, time, this.options.bounceEasing); return true; }, disable: function() { this.enabled = false; }, enable: function() { this.enabled = true; }, refresh: function() { var rf = this.wrapper.offsetHeight; this.wrapperHeight = this.wrapper.clientHeight; this.scrollerHeight = this.scroller.offsetHeight; this.maxScrollY = this.wrapperHeight - this.scrollerHeight; if (this.maxScrollY > 0) { this.maxScrollY = 0; } this.endTime = 0; this.wrapperOffset = utils.offset(this.wrapper); this.resetPosition(); }, scrollTo: function(y, time, easing) { easing = easing || utils.ease.circular; this.isInTransition = time > 0; this._transitionTimingFunction(easing.style); this._transitionTime(time); this._translate(y); }, scrollToElement: function(el, time, offsetY, easing) { el = el.nodeType ? el : this.scroller.querySelector(el); if (!el) { return; } var pos = utils.offset(el); pos.top -= this.wrapperOffset.top; if (offsetY === true) { offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2); } pos.top -= offsetY || 0; pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top; time = time === undefined || time === null || time === 'auto' ? Math.abs(this.y - pos.top) : time; this.scrollTo(pos.top, time, easing); }, _transitionTime: function(time) { time = time || 0; this.scrollerStyle[utils.style.transitionDuration] = time + 'ms'; }, _transitionTimingFunction: function(easing) { this.scrollerStyle[utils.style.transitionTimingFunction] = easing; }, _translate: function(y) { this.scrollerStyle[utils.style.transform] = 'translate3d(0px,' + y + 'px, 0px)'; this.y = y; }, _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); if (this.options.click) { eventType(this.wrapper, 'click', this, true); } 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); }, getComputedPosition: function() { var matrix = window.getComputedStyle(this.scroller, null); matrix = matrix[utils.style.transform].split(')')[0].split(', '); var x = +(matrix[12] || matrix[4]); var y = +(matrix[13] || matrix[5]); return { x: x, y: y }; }, handleEvent: function(e) { switch (e.type) { case 'touchstart': this._start(e); break; case 'touchmove': this._move(e); break; case 'touchend': this._end(e); break; case 'orientationchange': case 'resize': this._resize(); break; case 'transitionend': case 'webkitTransitionEnd': this._transitionEnd(e); break; } } }; Pan.utils = utils; return Pan;});
0 0
- 删减版iScroll
- iptables指南删减版
- iscroll
- iScroll
- iScroll
- iscroll
- 《雪国列车》逼韦恩斯坦妥协 英美将播未删减版
- 《南方周末》2013年新年献词未删减版
- 张小龙首次公开演讲(官方无删减版)
- 删减 ubuntu
- iScroll 4
- iscroll介绍
- iScroll 优化
- iscroll介绍
- iscroll介绍
- iScroll.js
- iscroll 例子
- iscroll原理
- C++文件读写详解(ofstream,ifstream,fstream)
- php---ajax传递多维数组到后台
- DockPanel去掉右键默认的菜单的方法:在该类上添加WM_CONTEXTMENU消息即可
- C++primer plus第六版课后编程练习答案7.3
- C++操作BMP文件
- 删减版iScroll
- android学习之路
- windows的iis做后门隐藏访问无日志
- SVN命令大全
- 去年的今天——系统重装
- Swift的基本语法
- 三维电影特效魔术师软件Sidefx Houdini FX v15.0.224 (Win/Mac)
- 彻底弄懂css中单位px和em,rem的区别 1.jpg
- H5移动端出生日期插件