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","file":"ipu.min.js","sourcesContent":["(function () {\n function setup(jQuery, iScroll, Hammer, FastClick) {\n\n /**\n * @class ipu UI的主对象,通过此对象实例UI组件\n *\n */\n\n var ipu = {\n version: '0.2.1'\n };\n\n// tap点击效果处理,只针对jquery上面的click事件,依赖touch事件\n(function (ipu, $) {\n var active = {};\n\n var options = defaultOptions = {\n distanceAllow: 10, // 最大移动距离,超过移除效果\n displayDelay: 100, // 延时显示时间,以防止是滚动操作\n hideDelay: 120, // 隐藏延时时间\n eventName: 'click', // 事件处理是click\n activeClass: 'ipu-active', // 激活时的class\n getHandleNode: function (node) { // 找到最先一级处理此click事件的元素\n if (!node || !node.nodeType) return;\n\n var distNode = null;\n var nodeArray = [];\n\n // 还有其它情形考虑,如a标签的跳转,或在原生元素添加事件属性的\n function findHander(inNode) {\n // 此方法适用于jquery, 1.12.4, 2.2.4, 3.2.1版本,_data方法以后可能会被移除。$.data是一些老版本写法\n var eventHandlers = ($._data || $.data)(inNode, 'events');\n\n if (eventHandlers) {\n eventHandlers = eventHandlers[options.eventName];\n }\n\n if (!eventHandlers) {\n return;\n }\n\n var thisNode = false;\n $.each(eventHandlers, function (index, handler) {\n if (handler.selector) {\n var objs = $(handler.selector, inNode);\n $.each(nodeArray, function (tIndex, tNode) {\n if (objs.is(tNode)) {\n distNode = tNode;\n return false;\n }\n });\n\n if (distNode) {\n return false; //\n }\n } else {\n thisNode = true; // 保存distNode,有可能有子节点满足条件,所以只保存此值为默认值\n }\n });\n\n if (thisNode && distNode == null) { // 如果没在子节点找到click事件,而当前节点又有click事件,就使用当前节点\n distNode = inNode;\n }\n\n return distNode;\n }\n\n while (!(\"tagName\" in node) || !findHander(node)) {\n if (!node.parentNode || node.parentNode.nodeType != 1) {\n break;\n }\n nodeArray.push(node);\n node = node.parentNode;\n }\n\n return distNode;\n }\n };\n\n function getOriginalEvent(e) {\n return e.originalEvent || e;\n }\n\n function getXY(e) {\n var x = e.touches ? e.touches[0].pageX : e.clientX;\n var y = e.touches ? e.touches[0].pageY : e.clientY;\n return [x, y];\n }\n\n //根据不同浏览器获取不同原生事件event\n var hasTouch = \"ontouchstart\" in window,\n START_EVENT = hasTouch ? 'touchstart' : 'mousedown',\n MOVE_EVENT = hasTouch ? 'touchmove' : 'mousemove',\n END_EVENT = hasTouch ? 'touchend' : 'mouseup',\n CANCEL_EVENT = hasTouch ? 'touchcancel' : '';\n\n $(function () {\n var startXY, tapEl, timeOutID;\n var dom = document.body;\n\n // force为false的时候,不用管timeOutID,在老的timeOutID未移除的情况下,有可能又产生了新的,\n // 导致else代码未被执行,导致老的点击元素class未被移除\n function removeClass(dom, force) {\n if (force && timeOutID) {\n window.clearTimeout(timeOutID);\n } else {\n $(dom).removeClass(options.activeClass);\n }\n }\n\n function removeActive(force) {\n if (force) {\n removeClass(tapEl, force);\n } else {\n window.setTimeout(removeClass, options.hideDelay, tapEl, force);\n }\n startXY = null;\n tapEl = null;\n }\n\n $(dom).bind(START_EVENT, function (e) {\n if (tapEl) { // 多点接触时处理\n removeActive(true);\n return;\n }\n\n e = getOriginalEvent(e);\n startXY = getXY(e);\n tapEl = options.getHandleNode(e.target);\n\n if (tapEl) {\n timeOutID = window.setTimeout(function (dom) {\n timeOutID = null;\n $(dom).addClass(options.activeClass);\n }, options.displayDelay, tapEl);\n }\n });\n\n $(dom).bind(MOVE_EVENT, function (e) {\n if (!tapEl) {\n return;\n }\n\n e = getOriginalEvent(e);\n\n var xy = getXY(e);\n if (startXY && (Math.abs(xy[0] - startXY[0]) > options.distanceAllow || Math.abs(xy[1] - startXY[1]) > options.distanceAllow)) {\n removeActive(true);\n }\n });\n\n $(dom).bind(END_EVENT, function (e) {\n if (tapEl) {\n removeActive();\n }\n });\n\n // 手机来电等非用户取消操作时触发事件\n if (CANCEL_EVENT) {\n $(dom).bind(CANCEL_EVENT, function (e) {\n if (tapEl) {\n removeActive();\n }\n });\n }\n });\n\n // 更新默认值\n active.setOptions = function (opts) {\n options = this.options = $.extend({}, defaultOptions, opts);\n };\n ipu.active = active;\n})(ipu || window, jQuery);\n\n\n(function (ipu, $, iscroll) {\n\n /**\n * @deprecated 推荐使用 {@link HammerCarousel}\n * @uses IScroll.js\n * @class 简单封装IScroll.js的snap功能,实现banner功能\n *\n * @example\n * <!-- 组件html结构如下,li里内容可自定义 -->\n * <div class=\"ipu-carousel ipu-hammer-carousel\">\n * <ul class=\"ipu-carousel-wrapper\">\n * <li ><img src=\"../../biz/img/01.jpg\" alt=\"\"></li>\n * <li ><img src=\"../../biz/img/02.jpg\" alt=\"\"></li>\n * <li ><img src=\"../../biz/img/03.jpg\" alt=\"\"></li>\n * <li ><img src=\"../../biz/img/04.jpg\" alt=\"\"></li>\n * </ul>\n * </div>\n *\n * @constructor 不能直接访问该类,使用ipu.carousel(slt, option)生成实例 {@link ipu#carousel}\n * @param {Dom|JqueryObj|String} slt jquery对象或者jquery选择器或Dom元素\n * @param {Object} option 组件配置参数,默认配置见 {@link #cfg-defaultOption}\n */\n function Carousel(slt, option) {\n this.option = option = $.extend({}, this.defaultOption, option);\n this.el = $(slt).eq(0); // 一次只能实例化一个\n this.autoPlay = option.autoPlay;\n this.hasIndicator = option.indicator;\n this.callBack = option.callBack;\n this.currentIndex = null;\n\n this._init();\n this.play();\n }\n\n Carousel.prototype = {\n /**\n * 组件默认配置项\n *\n * @cfg {Object} defaultOption\n * @cfg {Number} defaultOption.index 默认显示的项\n * @cfg {Boolean} defaultOption.autoPlay 是否自动播放\n * @cfg {Number} defaultOption.duration 自动播放间隔,单位ms\n * @cfg {Boolean} defaultOption.indicator 是否生成指示器\n * @cfg {Function} defaultOption.callBack 切换显示时的回调函数\n * @cfg {Number} defaultOption.callBack.index 当前显示项索引\n *\n */\n defaultOption: {\n index: null, // 默认显示索引,未设置时先查找对就active,未找到时是0\n autoPlay: false, // 是否自动播放\n duration: 3000, // 自动播放延时\n indicator: false, // 是否生成指示器\n callBack: null // 变更时回调函数\n },\n _init: function () {\n var wrapper = $(\">.ipu-carousel-wrapper\", this.el);\n var carouselItems = $(\">li\", wrapper);\n this.carouselItems = carouselItems;\n this.size = carouselItems.size();\n var that = this;\n\n if (this.option.index == null) {\n var activeIndex = carouselItems.filter(\".ipu-current\").index();\n this.option.index = activeIndex != -1 ? activeIndex : 0;\n }\n\n if (this.hasIndicator) {\n this._addIndicator();\n }\n $(window).resize(function () {\n that.refresh();\n });\n var scrollOpt = {\n snap: \"li\", // carousel效果\n momentum: false, // 移除惯性处理\n scrollX: true, // X轴移动\n scrollY: false,\n hScrollbar: false, // 没有纵向滚动条\n onScrollStart: function () {\n that._pause();\n },\n onTouchEnd: function () {\n },\n onScrollEnd: function () {\n that._end();\n }\n };\n this.iscroll = new iscroll(this.el.get(0), scrollOpt);\n this.show(this.option.index, 0);\n },\n /**\n * 停止自动播放\n */\n stop: function () {\n this._pause();\n this.autoPlay = false;\n },\n _pause: function () {\n if (this.autoPlay && this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n },\n /**\n * 显示上一项\n */\n prev: function () {\n var index = this.currentIndex == 0 ? this.size - 1 : this.currentIndex - 1;\n this.show(index);\n },\n /**\n * 显示下一项\n */\n next: function () {\n var index = this.currentIndex == this.size - 1 ? 0 : this.currentIndex + 1;\n this.show(index);\n },\n /**\n * 显示索引index对应的索\n *\n * @param {Number} index 显示项索引\n */\n show: function (index, time) {\n this._pause();\n this.iscroll.scrollToPage(index, 0, time);\n },\n /**\n * 开始自动播放\n */\n play: function () {\n this.autoPlay = true;\n this._play();\n },\n /**\n * 若窗口发生大小变更,调用此方法更新位移\n */\n refresh: function () {\n this.show(this.currentIndex);\n },\n _play: function () {\n if (this.autoPlay && !this.timeoutId) {\n var that = this;\n this.timeoutId = setTimeout(function () {\n that.timeoutId = null;\n that.next();\n }, that.option.duration);\n }\n },\n _end: function () {\n var currentIndex = this.iscroll.currPageX;\n if (currentIndex != this.currentIndex) {\n if (this.callBack) {\n this.callBack(currentIndex, this.currentIndex);\n }\n this.currentIndex = currentIndex;\n\n if (this.hasIndicator) {\n this.indicatorIndexs.eq(currentIndex).addClass(\"ipu-current\").siblings().removeClass(\"ipu-current\");\n }\n this.carouselItems.eq(currentIndex).addClass(\"ipu-current\").siblings().removeClass(\"ipu-current\");\n }\n this._play();\n },\n _addIndicator: function () {\n var html = \"\";\n for (var i = 0; i < this.size; i++) {\n html += \"<li></li>\";\n }\n html = \"<ul class='ipu-carousel-indicator'>\" + html + \"</ul>\";\n this.indicator = $(html).appendTo(this.el);\n this.indicatorIndexs = $(\"li\", this.indicator);\n },\n destroy: function () {\n // 自己怎么销毁,相关事件移除??\n this.iscroll.destroy();\n }\n };\n\n /**\n * @member ipu\n * 生成Carousel实例,参数信息见{@link Carousel#method-constructor}\n *\n * @param {String} slt\n * @param {Object} option\n * @returns {Carousel}\n */\n ipu.carousel = function (slt, option) {\n return new Carousel(slt, option);\n };\n\n})(ipu || window, jQuery, iScroll);\n\n// todo:添加判断平台如mobile ,tablet, pc,参考其它类似功能库,添加webview判断\n;(function (ipu, $) {\n \"use strict\";\n var device = {}; // Classes\n var classNames = [];\n var ua = navigator.userAgent;\n\n var android = ua.match(/(Android);?[\\s\\/]+([\\d.]+)?/);\n var ipad = ua.match(/(iPad).*OS\\s([\\d_]+)/);\n var ipod = ua.match(/(iPod)(.*OS\\s([\\d_]+))?/);\n var iphone = !ipad && ua.match(/(iPhone\\sOS)\\s([\\d_]+)/);\n\n device.ios = device.android = device.iphone = device.ipad = device.androidChrome = false;\n\n\n // Android\n if (android) {\n device.os = 'android';\n device.osVersion = android[2];\n device.android = true;\n device.androidChrome = ua.toLowerCase().indexOf('chrome') >= 0;\n }\n if (ipad || iphone || ipod) {\n device.os = 'ios';\n device.ios = true;\n }\n // iOS\n if (iphone && !ipod) {\n device.osVersion = iphone[2].replace(/_/g, '.');\n device.iphone = true;\n }\n if (ipad) {\n device.osVersion = ipad[2].replace(/_/g, '.');\n device.ipad = true;\n }\n if (ipod) {\n device.osVersion = ipod[3] ? ipod[3].replace(/_/g, '.') : null;\n device.iphone = true;\n }\n // iOS 8+ changed UA\n if (device.ios && device.osVersion && ua.indexOf('Version/') >= 0) {\n if (device.osVersion.split('.')[0] === '10') {\n device.osVersion = ua.toLowerCase().split('version/')[1].split(' ')[0];\n }\n }\n\n // Pixel Ratio\n device.pixelRatio = window.devicePixelRatio || 1;\n classNames.push('pixel-ratio-' + Math.floor(device.pixelRatio));\n if (device.pixelRatio >= 2) {\n classNames.push('retina');\n }\n\n // OS classes\n if (device.os) {\n classNames.push(device.os, device.os + '-' + device.osVersion.split('.')[0], device.os + '-' + device.osVersion.replace(/\\./g, '-'));\n if (device.os === 'ios') {\n var major = parseInt(device.osVersion.split('.')[0], 10);\n for (var i = major - 1; i >= 6; i--) {\n classNames.push('ios-gt-' + i);\n }\n }\n }\n\n device.wx = /MicroMessenger/i.test(ua); // 是否微信\n device.ipu = /ipumobile/i.test(ua); // 是否ipu环境运行\n\n if (device.wx) {\n classNames.push('wx');\n }\n if (device.ipu) {\n classNames.push('ipu');\n }\n\n var classPrev = \"ipu-\";\n\n // Add html classes\n if (classNames.length > 0) {\n $('html').addClass(classPrev + classNames.join(' ' + classPrev));\n }\n\n ipu.device = device;\n})(ipu || window, jQuery);\n\n// dtPicker 此版本最大值与最小值,存在问题,当时间跨过一天时\n// show方法调用时,若没有值,则为当前值,还是有值就不变动了,点了确认按钮后,就不再变动了\n// 日期范围的选择处理\n// 不选择字符串连接符,合并后占空间\n\n(function (ipu, $) {\n var Picker = ipu.Picker;\n var defaultPickerDate = new Date(); // 有些时间不齐全。如time,需要一个默认日期来协助运算\n\n /**\n * @class 日期选择器,替代默认的web日历选择,日期格式如下<br>\n * type=datetime:yyyy-mm-dd hh:mi<br>\n * type=date:yyyy-mm-dd<br>\n * type=time: hh:mi<br>\n * type=month: yyyy-mm<br>\n * type=hour: yyyy-mm-dd hh<br>\n *\n * @constructor 不能直接访问该,调用{@link ipu#dtPicker}生成实例\n * @param {object} option 组件参数,默认配置见 {@link #cfg-defaultOption}\n */\n function DtPicker(option) {\n this.option = $.extend({}, this.defaultOption, option);\n\n if (!Picker) {\n Picker = ipu.Picker;\n }\n this._init();\n }\n\n /**\n * 组件默认配置项\n *\n * @cfg {Object} defaultOption=\n * @cfg {String} defaultOption.template 组件模板html,不建议变更\n * @cfg {[String]} defaultOption.buttons=['取消', '确认', '清除'] 按钮名称\n * @cfg {[String]} defaultOption.labels=['年', '月', '日', '时', '分'] 年月日标签\n * @cfg {datetime|time|date|hour|month} defaultOption.type='datetime' 日期类型\n * @cfg {Boolean} defaultOption.hasClear=false 是否显示清除按钮\n * @cfg {Date} defaultOption.beginDate=null 日期开始时间,默认设置为当时间前5年\n * @cfg {Date} defaultOption.endDate=null 日期结束时间,默认设置为开始时间后10年\n * @cfg {Function} defaultOption.callBack=null 点击按钮时的回调函数,回调的参数同{@link #show show()}法设置 的回调\n */\n DtPicker.prototype.defaultOption = {\n template: '<div class=\"ipu-poppicker ipu-dtpicker\">'\n + '<div class=\"ipu-poppicker-header\">'\n + '<button class=\"ipu-btn ipu-btn-s ipu-poppicker-btn-cancel\">取消</button>'\n + '<button class=\"ipu-btn ipu-btn-s ipu-poppicker-btn-ok\">确定</button>'\n + '<button class=\"ipu-btn ipu-btn-s ipu-poppicker-btn-clear\">清除</button>'\n + '</div>'\n + '<div class=\"ipu-poppicker-title\">'\n + '<label class=\"ipu-dtpicker-y\"></label>'\n + '<label class=\"ipu-dtpicker-m\"></label>'\n + '<label class=\"ipu-dtpicker-d\"></label>'\n + '<label class=\"ipu-dtpicker-h\"></label>'\n + '<label class=\"ipu-dtpicker-mi\"></label>'\n + '</div>'\n + '<div>'\n + '<div class=\"ipu-poppicker-body\">'\n + '<div class=\"ipu-picker\" data-id=\"picker-y\">'\n + '<div class=\"ipu-picker-selectbox\"></div>'\n + '<ul></ul>'\n + '</div>'\n + '<div class=\"ipu-picker\" data-id=\"picker-m\">'\n + '<div class=\"ipu-picker-selectbox\"></div>'\n + '<ul></ul>'\n + '</div>'\n + '<div class=\"ipu-picker\" data-id=\"picker-d\">'\n + '<div class=\"ipu-picker-selectbox\"></div>'\n + '<ul></ul>'\n + '</div>'\n + '<div class=\"ipu-picker\" data-id=\"picker-h\">'\n + '<div class=\"ipu-picker-selectbox\"></div>'\n + '<ul></ul>'\n + '</div>'\n + '<div class=\"ipu-picker\" data-id=\"picker-mi\">'\n + '<div class=\"ipu-picker-selectbox\"></div>'\n + '<ul></ul>'\n + '</div>'\n + '</div>'\n + '</div>',\n buttons: ['取消', '确认', '清除'],\n labels: ['年', '月', '日', '时', '分'],\n type: 'datetime',\n customData: {},\n hasClear: false,\n beginDate: null,\n endDate: null,\n callBack: null\n };\n\n DtPicker.prototype._init = function () {\n var self = this;\n this.mask = this.createMask();\n\n var _picker = this.holder = $(this.option.template).appendTo(\"body\");\n var ui = self.ui = {\n picker: this.holder,\n ok: $('.ipu-poppicker-btn-ok', _picker),\n cancel: $('.ipu-poppicker-btn-cancel', _picker),\n clear: $('.ipu-poppicker-btn-clear', _picker),\n buttons: $('.ipu-poppicker-header .ipu-btn', _picker),\n labels: $('.ipu-poppicker-title label', _picker)\n };\n\n\n ui.i = new Picker($('[data-id=\"picker-mi\"]', _picker), {listen: false}); // 分钟变更无需要处理\n\n ui.h = new Picker($('[data-id=\"picker-h\"]', _picker), { // 小时变更,有最小值或最大值,需要变更分钟\n listen: false,\n onChange: function (item, index) {\n if (index !== null && (self.option.beginMonth || self.option.endMonth)) {\n self._createMinutes();\n }\n }\n });\n\n ui.d = new Picker($('[data-id=\"picker-d\"]', _picker), { //仅提供了beginDate时,触发day,hours,minutes的change\n listen: false,\n onChange: function (item, index) {\n if (index !== null && (self.option.beginMonth || self.option.endMonth)) {\n self._createHours();\n }\n }\n });\n\n ui.m = new Picker($('[data-id=\"picker-m\"]', _picker), { // 月变更时,总要变更day\n listen: false,\n onChange: function (item, index) {\n if (index !== null) {\n self._createDay();\n }\n }\n });\n\n ui.y = new Picker($('[data-id=\"picker-y\"]', _picker), { // 年发生变更,如果没有结束月,此时有所有的月,是不需要变更月的,只需要变更day\n listen: false,\n onChange: function (item, index) {\n if (index != null) {\n if (self.option.beginMonth || self.option.endMonth) {\n self._createMonth();\n } else {\n self._createDay();\n }\n }\n }\n });\n\n\n self._create();\n\n //设定label\n self._setLabels();\n self._setButtons();\n //设定类型\n ui.picker.attr('data-type', this.option.type);\n\n //设定默认值\n\n self._setSelectedValue(this.option.value);\n\n //防止滚动穿透 TODO:待确认情况\n /* self.ui.picker.addEventListener($.EVENT_START, function (event) {\n event.preventDefault();\n }, false);\n self.ui.picker.addEventListener($.EVENT_MOVE, function (event) {\n event.preventDefault();\n }, false);*/\n };\n\n /**\n * 返回当前选中的日期,只有在点确认时,返回的才是正确的值,在点清除、或取消后,调用此方法返回的值不可控\n *\n * @return 选择的日期信息\n * @return {datetime|time|date|hour|month} return.type 日期类型\n * @return {String} return.text 日期文本(text字段)拼接,格式yyyy-mm-dd hh:mi 根据上面的日期类型返回对应字符串\n * @return {String} return.value 日期项值(value字段)拼接\n * @return {Object} return.y 选择的年项\n * @return {Object} return.m 选择的月项\n * @return {Object} return.d 选择的日项\n * @return {Object} return.h 选择的时项\n * @return {Object} return.i 选择的分项\n * @return {Function} return.toString 返回value字段的值\n */\n DtPicker.prototype.getSelected = function () {\n var self = this;\n var ui = self.ui;\n var type = self.option.type;\n var selected = {\n type: type,\n y: ui.y.getSelectedItem(),\n m: ui.m.getSelectedItem(),\n d: ui.d.getSelectedItem(),\n h: ui.h.getSelectedItem(),\n i: ui.i.getSelectedItem(),\n toString: function () {\n return this.value;\n }\n };\n switch (type) {\n case 'datetime':\n selected.value = selected.y.value + '-' + selected.m.value + '-' + selected.d.value + ' ' + selected.h.value + ':' + selected.i.value;\n selected.text = selected.y.text + '-' + selected.m.text + '-' + selected.d.text + ' ' + selected.h.text + ':' + selected.i.text;\n break;\n case 'date':\n selected.value = selected.y.value + '-' + selected.m.value + '-' + selected.d.value;\n selected.text = selected.y.text + '-' + selected.m.text + '-' + selected.d.text;\n break;\n case 'time':\n selected.value = selected.h.value + ':' + selected.i.value;\n selected.text = selected.h.text + ':' + selected.i.text;\n break;\n case 'month':\n selected.value = selected.y.value + '-' + selected.m.value;\n selected.text = selected.y.text + '-' + selected.m.text;\n break;\n case 'hour':\n selected.value = selected.y.value + '-' + selected.m.value + '-' + selected.d.value + ' ' + selected.h.value;\n selected.text = selected.y.text + '-' + selected.m.text + '-' + selected.d.text + ' ' + selected.h.text;\n break;\n }\n return selected;\n };\n\n DtPicker.prototype._setSelectedValue = function (value) {\n var self = this;\n var ui = self.ui;\n\n if (!value) {\n if (this.option.type == 'time') {\n value = '00:00';\n } else {\n value = defaultPickerDate.getFullYear() + '-' + (defaultPickerDate.getMonth() + 1) + '-' + defaultPickerDate.getDate() + ' '\n + defaultPickerDate.getHours() + ':' + defaultPickerDate.getMinutes();\n }\n }\n var parsedValue = self._parseSetValue(value);\n\n ui.y.setListen(true);\n ui.m.setListen(false);\n ui.d.setListen(false);\n ui.h.setListen(false);\n ui.i.setListen(false);\n ui.y.setSelectedValue(parsedValue.y);\n\n ui.m.setListen(true);\n ui.m.setSelectedValue(parsedValue.m);\n\n ui.d.setListen(true);\n ui.d.setSelectedValue(parsedValue.d);\n\n ui.h.setListen(true);\n ui.h.setSelectedValue(parsedValue.h);\n\n ui.i.setListen(true);\n ui.i.setSelectedValue(parsedValue.i);\n\n this.value = this.getSelected().value;\n };\n\n /**\n * 设置日期值,value为字符串时,格式请参照 yyyy-mm-dd hh:mi具体格式与配置项type相关\n *\n * @param {String|Date} value\n */\n DtPicker.prototype.setSelectedValue = function (value) {\n this._setSelectedValue(value);\n };\n\n /**\n * 是否润年\n *\n * @param {Number} year 年份\n * @returns {Boolean}\n */\n DtPicker.prototype.isLeapYear = function (year) {\n return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);\n };\n\n DtPicker.prototype._inArray = function (array, item) {\n for (var index in array) {\n var _item = array[index];\n if (_item === item) return true;\n }\n return false;\n };\n\n DtPicker.prototype.getDayNum = function (year, month) {\n var self = this;\n if (self._inArray([1, 3, 5, 7, 8, 10, 12], month)) {\n return 31;\n } else if (self._inArray([4, 6, 9, 11], month)) {\n return 30;\n } else if (self.isLeapYear(year)) {\n return 29;\n } else {\n return 28;\n }\n };\n\n DtPicker.prototype._fill = function (num) {\n num = num.toString();\n if (num.length < 2) {\n num = 0 + num;\n }\n return num;\n };\n\n DtPicker.prototype._isBeginYear = function () {\n return this.option.beginYear === parseInt(this.ui.y.getSelectedValue());\n };\n\n DtPicker.prototype._isBeginMonth = function () {\n return this.option.beginMonth && this._isBeginYear() && this.option.beginMonth === parseInt(this.ui.m.getSelectedValue());\n };\n\n DtPicker.prototype._isBeginDay = function () {\n return this._isBeginMonth() && this.option.beginDay === parseInt(this.ui.d.getSelectedValue());\n };\n\n DtPicker.prototype._isBeginHours = function () {\n return this._isBeginDay() && this.option.beginHours === parseInt(this.ui.h.getSelectedValue());\n };\n\n DtPicker.prototype._isEndYear = function () {\n return this.option.endYear === parseInt(this.ui.y.getSelectedValue());\n };\n\n DtPicker.prototype._isEndMonth = function () {\n return this.option.endMonth && this._isEndYear() && this.option.endMonth === parseInt(this.ui.m.getSelectedValue());\n };\n\n DtPicker.prototype._isEndDay = function () {\n return this._isEndMonth() && this.option.endDay === parseInt(this.ui.d.getSelectedValue());\n };\n\n DtPicker.prototype._isEndHours = function () {\n return this._isEndDay() && this.option.endHours === parseInt(this.ui.h.getSelectedValue());\n };\n\n DtPicker.prototype._createYear = function () {\n var self = this;\n var option = self.option;\n var ui = self.ui;\n\n //生成年列表\n var yArray = [];\n if (option.customData.y) {\n yArray = option.customData.y;\n } else {\n var yBegin = option.beginYear;\n var yEnd = option.endYear;\n for (var y = yBegin; y <= yEnd; y++) {\n yArray.push({\n text: y + '',\n value: y\n });\n }\n }\n ui.y.setItems(yArray);\n };\n\n DtPicker.prototype._createMonth = function () {\n var self = this;\n var option = self.option;\n var ui = self.ui;\n\n //生成月列表\n var mArray = [];\n if (option.customData.m) {\n mArray = option.customData.m;\n } else {\n var m = option.beginMonth && self._isBeginYear() ? option.beginMonth : 1;\n var maxMonth = option.endMonth && self._isEndYear() ? option.endMonth : 12;\n for (; m <= maxMonth; m++) {\n var val = self._fill(m);\n mArray.push({\n text: val,\n value: m\n });\n }\n }\n ui.m.setItems(mArray);\n };\n\n DtPicker.prototype._createDay = function () {\n var self = this;\n var option = self.option;\n var ui = self.ui;\n\n //生成日列表\n var dArray = [];\n if (option.customData.d) {\n dArray = option.customData.d;\n } else {\n var d = self._isBeginMonth() ? option.beginDay : 1;\n var maxDay = self._isEndMonth() ? option.endDay : self.getDayNum(parseInt(this.ui.y.getSelectedValue()), parseInt(this.ui.m.getSelectedValue()));\n for (; d <= maxDay; d++) {\n var val = self._fill(d);\n dArray.push({\n text: val,\n value: d\n });\n }\n }\n ui.d.setItems(dArray);\n //current = current || ui.d.getSelectedValue();\n //ui.d.setSelectedValue(current);\n };\n\n DtPicker.prototype._createHours = function () {\n var self = this;\n var option = self.option;\n var ui = self.ui;\n //生成时列表\n var hArray = [];\n if (option.customData.h) {\n hArray = option.customData.h;\n } else {\n var h = self._isBeginDay() ? option.beginHours : 0;\n var maxHours = self._isEndDay() ? option.endHours : 23;\n for (; h <= maxHours; h++) {\n var val = self._fill(h);\n hArray.push({\n text: val,\n value: h\n });\n }\n }\n ui.h.setItems(hArray);\n //ui.h.setSelectedValue(current);\n };\n\n DtPicker.prototype._createMinutes = function () {\n var self = this;\n var option = self.option;\n var ui = self.ui;\n\n //生成分列表\n var iArray = [];\n if (option.customData.i) {\n iArray = option.customData.i;\n } else {\n var i = self._isBeginHours() ? option.beginMinutes : 0;\n var maxMinutes = self._isEndHours() ? option.endMinutes : 59;\n for (; i <= maxMinutes; i++) {\n var val = self._fill(i);\n iArray.push({\n text: val,\n value: i\n });\n }\n }\n ui.i.setItems(iArray);\n //ui.i.setSelectedValue(current);\n };\n\n DtPicker.prototype._setLabels = function () {\n var self = this;\n var option = self.option;\n var ui = self.ui;\n ui.labels.each(function (i, label) {\n label.innerText = option.labels[i];\n });\n };\n\n DtPicker.prototype._setButtons = function () {\n var self = this;\n var option = self.option;\n var ui = self.ui;\n ui.cancel.text(option.buttons[0]);\n ui.ok.text(option.buttons[1]);\n\n if (option.hasClear) {\n ui.clear.text(option.buttons[2])\n } else {\n ui.clear.hide();\n }\n\n ui.buttons.each(function (index) {\n $(this).click(function () {\n self.clickCall(index);\n })\n })\n };\n\n // 解析设置的值,目前是字符串,完整日期格式 2012-12-12 12:21\n // 对于time类型时,或未完整的时间值,使用defaultPickerDate来填充\n DtPicker.prototype._parseSetValue = function (value) {\n var now = defaultPickerDate;\n var type = this.option.type;\n\n var rs = {\n y: now.getFullYear(),\n m: now.getMonth() + 1,\n d: now.getDate(),\n h: now.getHours(),\n i: now.getMinutes()\n };\n\n if (value instanceof Date) {\n if (type == 'time') {\n value = value.getHours() + \":\" + value.getMinutes();\n } else {\n value = value.getFullYear() + '-' + (value.getMonth() + 1) + '-' + value.getDate() + ' '\n + value.getHours() + \":\" + value.getMinutes();\n }\n }\n\n var parts = value.replace(\":\", \"-\").replace(\" \", \"-\").split(\"-\");\n for (var i = 0, j = parts.length; i < j; i++) {\n parts[i] = parseInt(parts[i]);\n }\n\n if (type == 'datetime') {\n rs.y = parts[0];\n rs.m = parts[1];\n rs.d = parts[2]; //\n rs.h = parts[3]; //\n rs.i = parts[4];\n } else if (type == 'date') {\n rs.y = parts[0];\n rs.m = parts[1];\n rs.d = parts[2]; //\n rs.h = 0; //\n rs.i = 0;\n } else if (type == 'time') {\n rs.h = parts[0]; //\n rs.i = parts[1];\n } else if (type == 'hour') {\n rs.y = parts[0];\n rs.m = parts[1];\n rs.d = parts[2]; //\n rs.h = parts[3]; //\n rs.i = 0;\n } else if (type == 'month') {\n rs.y = parts[0];\n rs.m = parts[1];\n rs.d = 1; //\n rs.h = 0; //\n rs.i = 0;\n }\n\n return rs;\n };\n\n // 生成日期数据\n DtPicker.prototype._create = function () {\n var self = this;\n var option = this.option;\n var now = defaultPickerDate;\n var beginDate = option.beginDate;\n\n if (beginDate) { // 若有设置开始日期\n beginDate = this._parseSetValue(beginDate);\n option.beginYear = beginDate.y;\n option.beginMonth = beginDate.m;\n option.beginDay = beginDate.d;\n option.beginHours = beginDate.h;\n option.beginMinutes = beginDate.i;\n } else if (option.type == 'time') { // 未设置开始日期,但日期格式是time\n option.beginYear = now.getFullYear();\n option.beginMonth = now.getMonth() + 1;\n option.beginDay = now.getDate();\n option.beginHours = 0;\n option.beginMinutes = 0;\n } else {\n option.beginYear = now.getFullYear() - 5; // 其它,未设置开始日期,type也不为time,设置默认起始时间\n }\n\n var endDate = option.endDate;\n if (endDate) { //设定了结束日期\n endDate = this._parseSetValue(endDate);\n option.endYear = endDate.y;\n option.endMonth = endDate.m;\n option.endDay = endDate.d;\n option.endHours = endDate.h;\n option.endMinutes = endDate.i;\n } else if (option.type == 'time') {\n option.endYear = now.getFullYear();\n option.endMonth = now.getMonth() + 1;\n option.endDay = now.getDate();\n option.endHours = 23;\n option.endMinutes = 59;\n } else {\n option.endYear = option.beginYear + 10;\n }\n\n //生成\n self._createYear();\n self._createMonth();\n self._createDay();\n self._createHours();\n self._createMinutes();\n };\n\n /**\n * 设置组件日期范围\n *\n * @param {String|Date} beginDate 开始时间\n * @param {Stirng|Date} endDate 结束时间\n */\n DtPicker.prototype.setDateRange = function (beginDate, endDate) {\n this.option.beginDate = beginDate;\n this.option.endDate = endDate;\n this._create();\n };\n\n /**\n * 设置开始组件的开始据时间\n * @param {String|Date} date\n */\n DtPicker.prototype.setBeginDate = function (date) {\n this.option.beginDate = date;\n this._create();\n };\n\n /**\n * 设置组件的结束时间\n *\n * @param {String|Date} date\n */\n DtPicker.prototype.setEndDate = function (date) {\n this.option.endDate = date;\n this._create();\n };\n\n DtPicker.prototype.dispose = function () {\n var self = this;\n self.hide();\n setTimeout(function () {\n self.ui.picker.parentNode.removeChild(self.ui.picker);\n for (var name in self) {\n self[name] = null;\n delete self[name];\n }\n self.disposed = true;\n }, 300);\n };\n\n /**\n * 显示组件\n *\n * @param {Function} callBack 点击按钮时的回调函数,设置此参数会覆盖初始化时的回调函数\n * @param {Object} callBack.sltDate 当前选中的日期信息,具体格式,见方法{@link #getSelected getSelected()}的返回\n * @param {Number} callBack.index 被点击的按钮索引,0取消,1确认,2清除\n */\n DtPicker.prototype.show = function (callBack) {\n if (callBack) {\n this.option.callBack = callBack;\n }\n this.mask.show();\n this.setSelectedValue(this.value);\n this.holder.addClass(\"ipu-current\");\n };\n\n DtPicker.prototype.clickCall = function (index) {\n var self = this;\n var sltDate = self.getSelected();\n var rs = self.option.callBack.call(this, sltDate, index);\n if (rs !== false) {\n if (index == 1) { // 假定确认按钮在第二个位置,传回true则存储当前值\n self.value = sltDate.value;\n } else if (index == 2) {\n self.value = null;\n }\n self.hide();\n }\n };\n\n /**\n * 隐藏组件\n */\n DtPicker.prototype.hide = function () {\n this.mask.close();\n this.holder.removeClass(\"ipu-current\");\n };\n\n // 应该移除callback参数,提取出业成一个工具方法\n DtPicker.prototype.createMask = function (callback) {\n var self = this;\n var element = document.createElement('div');\n element.classList.add(\"ipu-picker-backup\");\n //element.addEventListener($.EVENT_MOVE, $.preventDefault);\n element.addEventListener('click', function () {\n self.clickCall(0);\n });\n var mask = [element];\n mask._show = false;\n mask.show = function () {\n mask._show = true;\n element.setAttribute('style', 'opacity:1');\n document.body.appendChild(element);\n return mask;\n };\n mask._remove = function () {\n if (mask._show) {\n mask._show = false;\n element.setAttribute('style', 'opacity:0');\n setTimeout(function () {\n var body = document.body;\n element.parentNode === body && body.removeChild(element);\n }, 350);\n }\n return mask;\n };\n mask.close = function () {\n if (mask._show) {\n if (callback) {\n if (callback() !== false) {\n mask._remove();\n }\n } else {\n mask._remove();\n }\n }\n };\n return mask;\n };\n\n /**\n * @member ipu\n * 生成DtPicker实例,参数信息见{@link DtPicker#method-constructor}\n *\n * @param {Object} option\n * @returns {DtPicker}\n */\n ipu.dtPicker = function (option) {\n return new DtPicker(option);\n };\n})(ipu || window, jQuery);\n\n// 更新方法和属性命名\n// 不能支持元素隐藏时,使用百比分处理移动距离。。。?\n// 支持两个以内容同时显示\n// 支持类似snap实现\n// 上下移动?\n// 理想是移除carousel.js的实现,用hammerCarousel.js实现所有相关功能\n// indicatorPosition: 'center', // left|right|center;暂不支持,不知道怎么支持在中间显示,用全宽度,配合point-event:none,可能ok,参考humUI和mui\n\n(function (ipu, $, Hammer) {\n /**\n * @class\n * @uses Hammer.js\n * 通过hammer.js实现的banner功能组件,\n * 因为实现轮播,显示第一项后,再显示第一项,所以第一项有被复制到添加到最后\n *\n * @example\n * <!-- 组件html结构如下,li里的内容用户可自定义 -->\n * <div class=\"ipu-carousel ipu-hammer-carousel\">\n * <ul class=\"ipu-carousel-wrapper\">\n * <li ><img src=\"../../biz/img/01.jpg\" alt=\"\"></li>\n * <li ><img src=\"../../biz/img/02.jpg\" alt=\"\"></li>\n * <li ><img src=\"../../biz/img/03.jpg\" alt=\"\"></li>\n * <li ><img src=\"../../biz/img/04.jpg\" alt=\"\"></li>\n * </ul>\n * </div>\n *\n * @constructor 不能直接访问该类,调用 {@link ipu#hammerCarousel}生成实例\n * @param {String|JqueryObj} slt\n * jquery选择器字符串或jquery对象,用来查找要被组件初始化化的dom\n * @param {Object} option 组件配置参数,默认配置见 {@link #cfg-defaultOption}\n */\n function HammerCarousel(slt, option) {\n this.option = $.extend({}, this.defaultOption, option);\n this.el = $(slt).get(0);\n this._init();\n }\n\n $.extend(HammerCarousel.prototype, {\n /**\n * 组件默认配置项\n *\n * @cfg {Object} defaultOption\n * @cfg {Number} defaultOption.index 初始化时显示第几项,用户未指定时,会查找子项内容上有ipu-current的项显示,默认显示第一项\n * @cfg {Boolean} defaultOption.loop 是否循环切换,只有轮播切换时,才能自动轮播\n * @cfg {Boolean} defaultOption.autoPlay 是否自动轮播\n * @cfg {Number} defaultOption.duration 自动轮播时的间隔时间,单位ms\n * @cfg {Boolean} defaultOption.indicator 是否生成banner提示器,true右下角出现小点\n * @cfg {Function} defaultOption.callBack 轮播显示某项时的回调函数\n * @cfg {Number} defaultOption.callBack.index 当前显示的项索引\n * @cfg {Function} defaultOption.clickBack\n * 切换项时被点击时的回调函数,此处主要是为了处理复制项与第一项的点击事件进行处理,\n * 让用户不关注点击的是第一项或是复制项,回调作用域为组件对象\n * @cfg {Number} defaultOption.clickBack.index 点击的项索引\n */\n defaultOption: {\n index: null,\n loop: false,\n autoPlay: false,\n duration: 3000,\n indicator: false,\n callBack: null,\n clickBack: null\n },\n _init: function () {\n this.wrapper = $(\">.ipu-carousel-wrapper\", this.el);\n this.carouselItems = $(\">li\", this.wrapper);\n this.itemSize = this.carouselItems.size(); // 子项数量\n\n this.showItemSize = 1; // 假设一屏默认显示1个,所以做循环显示只需要复制一个子项\n this.carouselItemWides = []; // 子项宽度尺寸\n this.currentIndex = 0; // 当前显示子项索引\n this.moveLen = 0; // 当前滚动移动距离\n this.lastItem = false; // index是0的时候,有可能显示的是第一项,也有可能显示的是复制项,这个参数用来标记是否复制项\n\n if (this.option.indicator) {\n this._addIndicator();\n }\n\n // 如果做循环展示,则要复制起始展示项到最后面\n if (this.option.loop) {\n this.carouselItems.slice(0, this.showItemSize).clone().appendTo(this.wrapper); // 这里假设每个元素宽度都是相等的\n }\n\n var that = this;\n if (this.option.clickBack) {\n $(\">li\", this.wrapper).each(function (i) {\n $(this).click(function () {\n that.option.clickBack.call(this, i % that.size);\n });\n })\n }\n\n this.hammer = new Hammer.Manager(this.el);\n this.hammer.add(new Hammer.Pan({direction: Hammer.DIRECTION_HORIZONTAL, threshold: 10}));\n this.hammer.on(\"panstart panmove panend pancancel\", Hammer.bindFn(this._onPan, this));\n\n this._sizeCount();\n $(window).resize(function () { // 在窗口尺寸变化时,更新尺寸信息\n that.refresh();\n });\n\n if (this.option.index == null) {\n var activeIndex = this.carouselItems.filter(\".ipu-current\").index();\n this.currentIndex = activeIndex != -1 ? activeIndex : 0;\n }\n\n this.show(this.currentIndex, false);\n },\n /**\n * 停止自动滚动\n */\n stop: function () {\n this._pause();\n this.option.autoPlay = false;\n },\n _pause: function () {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n },\n /**\n * 切换到上一项\n */\n prev: function () {\n var index;\n if(this.option.loop){\n index = this.currentIndex == 0 ? this.itemSize - 1 : this.currentIndex - 1;\n if (index == this.itemSize - 1) {\n this._show(this.itemSize, false);\n this.wrapper.width();\n }\n }else{\n index = (this.currentIndex - 1 + this.itemSize) % this.itemSize;\n }\n\n this._show(index);\n },\n /**\n * 切换到下一项\n */\n next: function () {//下一张\n var index\n if(this.option.loop){\n index = this.currentIndex == this.itemSize ? 1 : this.currentIndex + 1;\n if (index == 1) {\n this._show(0, false);\n this.wrapper.width();\n }\n } else {\n index = (this.currentIndex + 1) % this.itemSize;\n }\n\n this._show(index);\n },\n /**\n * 切换显示指定项\n *\n * @param {Number} index 要切换到的项索引\n *\n */\n show: function (index) {//跳到指定索引处\n var index = index % this.itemSize;\n if (index < 0) {\n index = this.itemSize + index;\n }\n this._show(index); // 默认追加动画\n },\n /**\n * 自动轮播\n */\n play: function () {\n this.option.autoPlay = true;\n this._play();\n },\n _play: function () {\n if (this.option.autoPlay && this.option.loop && !this.timeoutId) {\n var that = this;\n this.timeoutId = setTimeout(function () {\n that.timeoutId = null;//清空这个timeoutId,代表该次处理已经执行了\n that.next();\n }, that.option.duration);\n }\n },\n _addIndicator: function () {\n var html = \"\";\n for (var i = 0; i < this.itemSize; i++) {\n html += \"<li></li>\";\n }\n html = \"<ul class='ipu-carousel-indicator'>\" + html + \"</ul>\";\n this.indicator = $(html).appendTo(this.el);\n this.indicatorIndexs = $(\"li\", this.indicator);\n },\n _sizeCount: function () {\n this.wrapperWidth = this.wrapper.outerWidth(true);\n this.itemWidth = this.carouselItems.eq(0).outerWidth(true);\n this.mostSize = this.itemSize * this.itemWidth; // 宽度*数量\n $(this.wrapper).removeClass(\"ipu-carousel-animate\").width();\n this.carouselItemWides = [];\n\n var that = this;\n $(\">li\", this.wrapper).each(function (index, dom) { // 此处要注意,最后一个子项是后加进入的,要重新使用jquery处理一下,不能直接使用this.xx来处理\n that.carouselItemWides[index] = $(this).position().left;\n });\n },\n /**\n * 宽度信息或尺寸信息发生变更时,进行刷新计算\n * 判断是否需要重新计算尺寸,若宽度尺寸发生变化,进行重新尺寸计算\n */\n refresh: function () {\n if (this.wrapperWidth != this.wrapper.outerWidth(true)) {\n this._sizeCount();\n this._show(this.currentIndex, false); //新的位置\n }\n },\n _move: function (moveLen) { // 拖动时的处理\n this._pause();\n $(this.wrapper).removeClass(\"ipu-carousel-animate\");\n\n if(this.option.loop){\n var move = (this.moveLen - moveLen) % this.mostSize;\n move = (move + this.mostSize) % this.mostSize;\n\n }else{\n var move = this.moveLen - moveLen;\n if (move < 0) {\n move = move / 2;\n }else if(move > this.mostSize){\n move = this.mostSize + (move - this.mostSize)/2;\n }\n }\n\n this.displayMoveLen = move;\n move = -move + \"px\";\n $(this.wrapper).css(\"transform\", \"translate3d(\" + move + \", 0, 0)\");\n },\n _show: function (index, animate) { // 知道最终移动到的项时,调用\n if (animate !== false) { // 默认值为true\n animate = true;\n }\n\n this._pause();\n $(this.wrapper).toggleClass(\"ipu-carousel-animate\", animate);\n this.currentIndex = index % this.itemSize;\n this.lastItem = index == this.itemSize;\n\n this.moveLen = this.carouselItemWides[index];\n var move = -this.moveLen + \"px\";\n\n $(this.wrapper).css(\"transform\", \"translate3d(\" + move + \", 0, 0)\");\n\n var currentIndex = this.currentIndex;\n if (animate && this.option.callBack) {\n this.option.callBack(currentIndex, this.lastItem);//返回当前索引,以及是滞最后一项参数\n }\n\n if (this.indicator) {\n this.indicatorIndexs.eq(currentIndex).addClass(\"ipu-current\").siblings().removeClass(\"ipu-current\");\n }\n\n this._play();//处理自动播放\n },\n _onPan: function (ev) {\n var delta = ev.deltaX; // 内容往左,deltaX为正值\n\n // pancancel与panend,有效的pan事件结束与无效的pan事件结束?\n if (ev.type == 'panend' || ev.type == 'pancancel'){\n var value = delta / this.itemWidth;\n var intValue = parseInt(Math.abs(value)); // 取整数\n var decimal = Math.abs(value) % 1; // 取小数\n\n if (decimal > 0.2) { // 滑动超过页面宽20%;\n intValue = intValue + 1;\n }\n if (delta > 0) {\n intValue = -intValue;\n }\n var index;\n\n if(this.option.loop) {\n index = (this.currentIndex + intValue) % this.itemSize;\n index = (index + this.itemSize) % this.itemSize; // 因为可能是个负值,转换成正值\n\n // 当前位移大于一个项的长度,这由move方法导致的,所以此时只能是最后一项在显示,所以要显示最后一项\n if (index == 0 && this.displayMoveLen > this.itemWidth) {\n index = this.itemSize;\n }\n } else { // 非循环时\n index = this.currentIndex + intValue;\n if (index < 0) {\n index = 0;\n } else if (index > this.itemSize - 1) {\n index = this.itemSize - 1;\n }\n }\n\n this._show(index);\n } else if (ev.type == 'panmove') {\n this._move(delta);\n }\n }\n });\n\n /**\n * @member ipu\n * 生成HammerCarousel实例,参数信息见{@link HammerCarousel#method-constructor}\n *\n * @param {String} slt\n * @param {Object} option\n * @returns {HammerCarousel}\n */\n ipu.hammerCarousel = function (slt, option) {\n return new HammerCarousel(slt, option);\n };\n})(ipu || window, jQuery, Hammer);\n\n(function (ipu, $) {\n\n function __dealCssEvent(eventNameArr, callback) {\n var events = eventNameArr,\n i, dom = this;// jshint ignore:line\n\n function fireCallBack(e) {\n /*jshint validthis:true */\n if (e.target !== this) return;\n callback.call(this, e);\n for (i = 0; i < events.length; i++) {\n dom.off(events[i], fireCallBack);\n }\n }\n\n if (callback) {\n for (i = 0; i < events.length; i++) {\n dom.on(events[i], fireCallBack);\n }\n }\n }\n\n $.fn.transitionEnd = function (callback) {\n __dealCssEvent.call(this, ['webkitTransitionEnd', 'transitionend'], callback);\n return this;\n };\n\n var _modalTemplateTempDiv = document.createElement('div');\n\n var defaults = {\n modalTitle: '',\n modalStack: true,\n modalButtonOk: '确定',\n modalButtonCancel: '取消',\n modalPreloaderTitle: '加载中',\n modalContainer: document.body ? document.body : 'body'\n };\n\n ipu.modalStack = [];\n\n ipu.modalStackClearQueue = function () {\n if (ipu.modalStack.length) {\n (ipu.modalStack.shift())();\n }\n };\n\n ipu.modal = function (params) {\n params = params || {};\n var buttonsHTML = '';\n if (params.buttons && params.buttons.length > 0) {\n for (var i = 0; i < params.buttons.length; i++) {\n buttonsHTML += '<span class=\"ipu-modal-button' + (params.buttons[i].bold ? ' ipu-modal-button-bold' : '') + '\">' + params.buttons[i].text + '</span>';\n }\n }\n var extraClass = params.extraClass || '';\n var titleHTML = params.title ? '<div class=\"ipu-modal-title\">' + params.title + '</div>' : '';\n var textHTML = params.text ? '<div class=\"ipu-modal-text\">' + params.text + '</div>' : '';\n var afterTextHTML = params.afterText ? params.afterText : '';\n var noButtons = !params.buttons || params.buttons.length === 0 ? 'ipu-modal-no-buttons' : '';\n var verticalButtons = params.verticalButtons ? 'ipu-modal-buttons-vertical' : '';\n\n var modalHTML = '<div class=\"ipu-modal ' + extraClass + ' ' + noButtons + '\"><div class=\"ipu-modal-inner\">' + (titleHTML + textHTML + afterTextHTML) + '</div><div class=\"ipu-modal-buttons ' + verticalButtons + '\">' + buttonsHTML + '</div></div>';\n\n _modalTemplateTempDiv.innerHTML = modalHTML;\n\n var modal = $(_modalTemplateTempDiv).children();\n\n $(defaults.modalContainer).append(modal[0]);\n\n // Add events on buttons\n modal.find('.ipu-modal-button').each(function (index, el) {\n $(el).on('click', function (e) {\n if (params.buttons[index].close !== false) ipu.closeModal(modal);\n if (params.buttons[index].onClick) params.buttons[index].onClick(modal, e);\n if (params.onClick) params.onClick(modal, index);\n });\n });\n ipu.openModal(modal);\n return modal[0];\n };\n\n /**\n * @member ipu\n * 弹出警告消息\n *\n * @param {String} text 警句文本\n * @param {String} title 警告标题,可选参数\n * @param {Function} callbackOk 用户确认后的回调函数,可选参数\n */\n ipu.alert = function (text, title, callbackOk) {\n if (typeof title === 'function') {\n callbackOk = arguments[1];\n title = undefined;\n }\n return ipu.modal({\n text: text || '',\n title: typeof title === 'undefined' ? defaults.modalTitle : title,\n buttons: [{text: defaults.modalButtonOk, bold: true, onClick: callbackOk}]\n });\n };\n\n /**\n * @member ipu\n * 弹出确认消息\n *\n * @param {String} text 确认文本\n * @param {String} title 确认标题,可选参数\n * @param {Function} callbackOk 用户确认后的回调函数,可选参数\n * @param {Function} callbackCancel 用户确认后的回调函数,可选参数\n */\n ipu.confirm = function (text, title, callbackOk, callbackCancel) {\n if (typeof title === 'function') {\n callbackCancel = arguments[2];\n callbackOk = arguments[1];\n title = undefined;\n }\n return ipu.modal({\n text: text || '',\n title: typeof title === 'undefined' ? defaults.modalTitle : title,\n buttons: [\n {text: defaults.modalButtonCancel, bold: true, onClick: callbackCancel},\n {text: defaults.modalButtonOk, bold: true, onClick: callbackOk}\n ]\n });\n };\n\n /**\n * @member ipu\n * 弹出输入框\n *\n * @param {String} text 输入提示文本\n * @param {String} title 输入提示标题,可选参数\n * @param {Function} callbackOk 用户确认后的回调函数,可选参数\n * @param {Function} callbackCancel 用户确认后的回调函数,可选参数\n */\n ipu.prompt = function (text, title, callbackOk, callbackCancel) {\n if (typeof title === 'function') {\n callbackCancel = arguments[2];\n callbackOk = arguments[1];\n title = undefined;\n }\n return ipu.modal({\n text: text || '',\n title: typeof title === 'undefined' ? defaults.modalTitle : title,\n afterText: '<input type=\"text\" class=\"ipu-modal-text-input\">',\n buttons: [\n {\n text: defaults.modalButtonCancel\n },\n {\n text: defaults.modalButtonOk,\n bold: true\n }\n ],\n onClick: function (modal, index) {\n if (index === 0 && callbackCancel) callbackCancel($(modal).find('.ipu-modal-text-input').val());\n if (index === 1 && callbackOk) callbackOk($(modal).find('.ipu-modal-text-input').val());\n }\n });\n };\n\n var minLoad = false; // 是否最小时间调用方式\n var loadOverTime = false; // 是否超过最小调用时间\n var loadEnd = false; // 是否调用结束\n var loadTimeOut = null; // 延时调用ID\n\n /**\n * @member ipu\n * 弹出加载消息提示\n *\n * @param {String} title 加载提示文本\n * @param {Number} minTime 消息最小显示时间,单位ms,可选参数\n */\n ipu.showPreloader = function (title, minTime) {\n ipu.hidePreloader(true);\n\n ipu.showPreloader.preloaderModal = ipu.modal({\n title: title || defaults.modalPreloaderTitle,\n text: '<div class=\"ipu-preloader\"></div>'\n });\n\n if (minTime) {\n minLoad = true;\n loadTimeOut = setTimeout(function () {\n loadOverTime = true;\n if (loadEnd) {\n ipu.hidePreloader();\n }\n }, minTime);\n }\n\n return ipu.showPreloader.preloaderModal;\n };\n\n /**\n * @member ipu\n * 隐藏加载消息提示\n *\n * @param {Boolean} force 是否强制隐藏,不管最小提示时间,可选\n */\n ipu.hidePreloader = function (force) {\n if (force || !minLoad || (minLoad && loadOverTime)) {\n if (force && loadTimeOut) {\n window.clearTimeout(loadTimeOut);\n }\n ipu.showPreloader.preloaderModal && ipu.closeModal(ipu.showPreloader.preloaderModal);\n minLoad = false; // 重置各标志位\n loadOverTime = false;\n loadEnd = false;\n loadTimeOut = null;\n } else {\n loadEnd = true;\n }\n };\n\n /**\n * @member ipu\n * 显示加载状态\n */\n ipu.showIndicator = function () {\n if ($('.ipu-preloader-indicator-modal')[0]) return;\n $(defaults.modalContainer).append('<div class=\"ipu-preloader-indicator-overlay\"></div><div class=\"ipu-preloader-indicator-modal\"><span class=\"ipu-preloader ipu-preloader-white\"></span></div>');\n };\n\n /**\n * @member ipu\n * 隐藏加载状态\n */\n ipu.hideIndicator = function () {\n $('.ipu-preloader-indicator-overlay, .ipu-preloader-indicator-modal').remove();\n };\n\n /**\n * @member ipu\n * 显示操作选项\n *\n * @param{[[Object]]} actions\n * @param {Object} actions.Object\n * @param {String} actions.Object.text 操作名称\n * @param {Boolean} actions.Object.label 是否标签,非标签就是操作项,操作项有后续的配置,标签项无须后续配置项\n * @param {String:warning} actions.Object.color 样式,可选\n * @param {String:warning} actions.Object.bg 背景样式,可选\n * @param {Function} actions.Object.onClick 点击时回调函数\n */\n ipu.actions = function (params) {\n var modal, groupSelector, buttonSelector;\n params = params || [];\n\n if (params.length > 0 && !$.isArray(params[0])) {\n params = [params];\n }\n var modalHTML;\n var buttonsHTML = '';\n for (var i = 0; i < params.length; i++) {\n for (var j = 0; j < params[i].length; j++) {\n if (j === 0) buttonsHTML += '<div class=\"ipu-actions-modal-group\">';\n var button = params[i][j];\n var buttonClass = button.label ? 'ipu-actions-modal-label' : 'ipu-actions-modal-button';\n if (button.bold) buttonClass += ' ipu-actions-modal-button-bold';\n if (button.color) buttonClass += ' ipu-color-' + button.color;\n if (button.bg) buttonClass += ' ipu-bg-' + button.bg;\n if (button.disabled) buttonClass += ' disabled';\n buttonsHTML += '<span class=\"' + buttonClass + '\">' + button.text + '</span>';\n if (j === params[i].length - 1) buttonsHTML += '</div>';\n }\n }\n modalHTML = '<div class=\"ipu-actions-modal\">' + buttonsHTML + '</div>';\n _modalTemplateTempDiv.innerHTML = modalHTML;\n modal = $(_modalTemplateTempDiv).children();\n $(defaults.modalContainer).append(modal[0]);\n groupSelector = '.ipu-actions-modal-group';\n buttonSelector = '.ipu-actions-modal-button';\n\n var groups = modal.find(groupSelector);\n groups.each(function (index, el) {\n var groupIndex = index;\n $(el).children().each(function (index, el) {\n var buttonIndex = index;\n var buttonParams = params[groupIndex][buttonIndex];\n var clickTarget;\n if ($(el).is(buttonSelector)) clickTarget = $(el);\n // if (toPopover && $(el).find(buttonSelector).length > 0) clickTarget = $(el).find(buttonSelector);\n\n if (clickTarget) {\n clickTarget.on('click', function (e) {\n if (buttonParams.close !== false) ipu.closeModal(modal);\n if (buttonParams.onClick) buttonParams.onClick(modal, e);\n });\n }\n });\n });\n ipu.openModal(modal);\n return modal[0];\n };\n\n //显示一个消息,会在2秒钟后自动消失\n /**\n * @member ipu\n * 悬浮提示消息\n *\n * @param {String} msg 消息文本\n * @param {Number} duration=2000 消息显示时间,单位ms\n */\n ipu.toast = function (msg, duration, extraclass) {\n var $toast = $('<div class=\"ipu-modal ipu-toast ' + (extraclass || '') + '\">' + msg + '</div>').appendTo(document.body);\n ipu.openModal($toast, function () {\n setTimeout(function () {\n ipu.closeModal($toast);\n }, duration || 2000);\n });\n };\n\n ipu.openModal = function (modal, cb) {\n modal = $(modal);\n var isModal = modal.hasClass('ipu-modal'),\n isNotToast = !modal.hasClass('ipu-toast');\n isNotToast = false; // 强制打开新窗口\n\n if ($('.ipu-modal.ipu-modal-in:not(.ipu-modal-out)').length && defaults.modalStack && isModal && isNotToast) {\n ipu.modalStack.push(function () {\n ipu.openModal(modal, cb);\n });\n return;\n }\n\n var isPopup = modal.hasClass('ipu-popup');\n var isLoginScreen = modal.hasClass('ipu-login-screen');\n var isPickerModal = modal.hasClass('ipu-picker-modal');\n var isToast = modal.hasClass('ipu-toast');\n\n if (isModal) {\n modal.show();\n modal.css({\n marginTop: -Math.round(modal.outerHeight() / 2) + 'px'\n });\n }\n\n if (isToast) {\n modal.css({\n marginLeft: -Math.round(modal.outerWidth() / 2) + 'px' //1.185 是初始化时候的放大效果\n });\n }\n\n var overlay;\n if (!isLoginScreen && !isPickerModal && !isToast) {\n if ($('.ipu-modal-overlay').length === 0 && !isPopup) {\n $(defaults.modalContainer).append('<div class=\"ipu-modal-overlay\"></div>');\n }\n if ($('.ipu-popup-overlay').length === 0 && isPopup) {\n $(defaults.modalContainer).append('<div class=\"ipu-popup-overlay\"></div>');\n }\n overlay = isPopup ? $('.ipu-popup-overlay') : $('.ipu-modal-overlay');\n }\n\n //Make sure that styles are applied, trigger relayout;\n var clientLeft = modal[0].clientLeft;\n\n // Trugger open event\n modal.trigger('open');\n\n // Picker modal body class\n if (isPickerModal) {\n $(defaults.modalContainer).addClass('ipu-with-picker-modal');\n }\n\n // Classes for transition in\n if (!isLoginScreen && !isPickerModal && !isToast) {\n overlay.addClass('ipu-modal-overlay-visible');\n }\n modal.removeClass('ipu-modal-out').addClass('ipu-modal-in').transitionEnd(function (e) {\n if (modal.hasClass('ipu-modal-out')) modal.trigger('closed');\n else modal.trigger('opened');\n });\n // excute callback\n if (typeof cb === 'function') {\n cb.call(this);\n }\n return true;\n };\n\n ipu.closeModal = function (modal) {\n modal = $(modal || '.ipu-modal-in');\n if (typeof modal !== 'undefined' && modal.length === 0) {\n return;\n }\n var isModal = modal.hasClass('ipu-modal'),\n isPopup = modal.hasClass('ipu-popup'),\n isToast = modal.hasClass('ipu-toast'),\n isLoginScreen = modal.hasClass('ipu-login-screen'),\n isPickerModal = modal.hasClass('ipu-picker-modal'),\n removeOnClose = modal.hasClass('ipu-remove-on-close'),\n overlay = isPopup ? $('.ipu-popup-overlay') : $('.ipu-modal-overlay');\n if (isPopup) {\n if (modal.length === $('.ipu-popup.ipu-modal-in').length) {\n overlay.removeClass('ipu-modal-overlay-visible');\n }\n }\n else if (!(isPickerModal || isToast)) {\n overlay.removeClass('ipu-modal-overlay-visible');\n }\n modal.trigger('close');\n\n // Picker modal body class\n if (isPickerModal) {\n $(defaults.modalContainer).removeClass('ipu-with-picker-modal');\n $(defaults.modalContainer).addClass('ipu-picker-modal-closing');\n }\n\n modal.removeClass('ipu-modal-in').addClass('ipu-modal-out').transitionEnd(function (e) {\n if (modal.hasClass('ipu-modal-out')) modal.trigger('closed');\n else modal.trigger('opened');\n\n if (isPickerModal) {\n $(defaults.modalContainer).removeClass('ipu-picker-modal-closing');\n }\n if (isPopup || isLoginScreen || isPickerModal) {\n modal.removeClass('ipu-modal-out').hide();\n if (removeOnClose && modal.length > 0) {\n modal.remove();\n }\n }\n else {\n modal.remove();\n }\n });\n if (isModal && defaults.modalStack) {\n ipu.modalStackClearQueue();\n }\n\n return true;\n };\n\n function handleClicks(e) {\n /*jshint validthis:true */\n var clicked = $(this);\n var url = clicked.attr('href');\n\n\n //Collect Clicked data- attributes\n /* var clickedData = clicked.dataset();\n\n // Popup\n var popup;\n if (clicked.hasClass('ipu-open-popup')) {\n if (clickedData.popup) {\n popup = clickedData.popup;\n }\n else popup = '.ipu-popup';\n ipu.popup(popup);\n }\n if (clicked.hasClass('ipu-close-popup')) {\n if (clickedData.popup) {\n popup = clickedData.popup;\n }\n else popup = '.ipu-popup.modal-in';\n ipu.closeModal(popup);\n }*/\n\n // Close Modal\n if (clicked.hasClass('ipu-modal-overlay')) {\n if ($('.ipu-modal.ipu-modal-in').length > 0 && defaults.modalCloseByOutside)\n ipu.closeModal('.ipu-modal.ipu-modal-in');\n if ($('.ipu-actions-modal.ipu-modal-in').length > 0 && defaults.actionsCloseByOutside)\n ipu.closeModal('.ipu-actions-modal.ipu-modal-in');\n\n }\n if (clicked.hasClass('ipu-popup-overlay')) {\n if ($('.ipu-popup.ipu-modal-in').length > 0 && defaults.popupCloseByOutside)\n ipu.closeModal('.ipu-popup.modal-in');\n }\n }\n\n $(document).on('click', ' .ipu-modal-overlay, .ipu-popup-overlay, .ipu-close-popup, .ipu-open-popup, .ipu-close-picker', handleClicks);\n})(ipu || window, jQuery);\n\n(function (ipu, $) {\n /**\n * @class 导航切换组件\n *\n * @example\n *\n * <!-- 组件的html分成导航和内容两部分,一般与flex栅格配合布局-->\n *\n * <!-- 组件导航部分 -->\n * <nav class=\"ipu-navbar \">\n * <a class=\"ipu-navbar-item \" href=\"javascript:;\">\n * <span class=\"ipu-icon fa fa-home\"></span>\n * <span class=\"ipu-navbar-item-label\">插件</span>\n * </a>\n * <a class=\"ipu-navbar-item \" href=\"javascript:;\">\n * <span class=\"ipu-icon fa fa-dashcube\"></span>\n * <span class=\"ipu-navbar-item-label\">JS组件</span>\n * </a>\n * <a class=\"ipu-navbar-item ipu-current\" href=\"javascript:;\">\n * <span class=\"ipu-icon fa fa-map\"></span>\n * <span class=\"ipu-navbar-item-label\">静态组件</span>\n * </a>\n * <a class=\"ipu-navbar-item\" href=\"javascript:;\">\n * <span class=\"ipu-icon fa fa-mortar-board\"></span>\n * <span class=\"ipu-navbar-item-label\">更多</span>\n * </a>\n * </nav>\n *\n * <!-- 内容部分 -->\n * <div class=\"ipu-nav-content\">\n * <ul>\n * <li>\n * 自定义内容1\n * </li>\n * <li>\n * 自定义内容\n * </li>\n * <li>\n * 自定义内容\n * </li>\n * <li>\n * 自定义内容\n * </li>\n * </ul>\n * </div>\n *\n *\n * @constructor 不能直接访问该类,调用{@link ipu#navBar ipu.navBar(slt, option)}生成实例\n * @param {String|jqueryObj} slt jquery选择器字符串或jquery对象,用来查找要被组件初始化化的dom\n * @param {Object} option 组件配置参数,默认配置见 {@link #cfg-defaultOption}\n */\n function NavBar(slt, option) {\n this.option = $.extend({}, this.defaultOption, option);\n this.content = $(this.option.contentSlt);\n this.nav = $(slt);\n this.wrapper = $(\">ul\", this.content);\n this.contents = $(\">li\", this.wrapper);\n this.navs = $(\">a\", this.nav);\n var me = this;\n\n var activeIndex = this.navs.filter(\".ipu-current\").index(); // 查找默认有active的索引\n if (activeIndex == -1) {\n activeIndex = this.contents.filter(\".ipu-current\").index(); // 查找默认有active的索引\n }\n this.option.index = activeIndex != -1 ? activeIndex : 0;\n\n if (!this.option.animate) {\n this.wrapper.addClass(\"ipu-no-animation\")\n }\n\n this.navs.each(function (index, i) {\n $(this).click(function () {\n me.show(index);\n });\n });\n\n this.lastIndex = null;\n this.currentIndex = null;\n me.show(this.option.index);\n }\n\n /**\n * 组件默认配置项\n *\n * @cfg {Object} defaultOption\n * @cfg {Boolean} defaultOption.animate=false 切换时是否添加动画效果\n * @cfg {Dom|String|JqueryObj} defaultOption.contentSlt='.ipu-nav-content' 内容dom选择器,页面有多个navBar组件时,需要设置此值\n * @cfg {Function} defaultOption.callBack 切换时的回调函数\n * @cfg {Number} defaultOption.callBack.index 当前显示项索引\n */\n NavBar.prototype.defaultOption = {\n animate: false,\n contentSlt: \".ipu-nav-content\",\n callBack: function (currentIndex, lastIndex) {\n }\n };\n\n /**\n * 显示第几项内容\n * @param {Number} index 显示内容项索引\n */\n NavBar.prototype.show = function (index) {\n if (this.currentIndex != index) {\n $(this.contents[index]).addClass(\"ipu-show\");\n\n if (this.option.animate) {\n if (this.lastIndex != null && this.lastIndex != index) {\n $(this.contents[this.lastIndex]).removeClass(\"ipu-show\"); // 隐藏上上个元素\n }\n\n if (this.currentIndex != null) { // 非第一次需要动画效果\n if (this.currentIndex < index) { // 需要内容为往左走,显示右边的内容\n if (this.lastIndex != null && this.lastIndex < this.currentIndex) { // 内容已经左走过了,则需要移除动画复原位置,再通过width()方法强制生效\n this.wrapper.addClass(\"ipu-no-animation\").removeClass(\"ipu-nav-content-right\").width(); // 可以强制刷新,默认jquery应该会将这些dom上的修改延时处理?\n }\n } else {\n if (this.lastIndex == null || this.lastIndex > this.currentIndex) { // 类似同上\n this.wrapper.addClass(\"ipu-no-animation\").addClass(\"ipu-nav-content-right\").width(); // 可以强制刷新不?\n }\n }\n this.wrapper.removeClass(\"ipu-no-animation\").toggleClass(\"ipu-nav-content-right\");\n }\n } else {\n $(this.contents[this.currentIndex]).removeClass(\"ipu-show\");\n }\n\n // 更新class,ipu-current状态\n $(this.contents[index]).addClass(\"ipu-current\").siblings(\".ipu-current\").removeClass(\"ipu-current\");\n $(this.navs[index]).addClass(\"ipu-current\").siblings(\".ipu-current\").removeClass(\"ipu-current\");\n\n this.lastIndex = this.currentIndex;\n this.currentIndex = index;\n\n if (this.option.callBack) {\n this.option.callBack(this.currentIndex, this.lastIndex);\n }\n }\n };\n\n /**\n * @member ipu\n * 生成NavBar实例,参数信息见{@link NavBar#method-constructor}\n *\n * @param {String} slt\n * @param {Object} option\n * @returns {NavBar}\n */\n ipu.navBar = function (slt, option) {\n return new NavBar(slt, option);\n };\n})(ipu || window, jQuery);\n\n(function (ipu, $) {\n function __dealCssEvent(eventNameArr, callback) {\n var events = eventNameArr,\n i, dom = this;// jshint ignore:line\n\n function fireCallBack(e) {\n if (e.target !== this) return;\n callback.call(this, e);\n for (i = 0; i < events.length; i++) {\n dom.off(events[i], fireCallBack);\n }\n }\n\n if (callback) {\n for (i = 0; i < events.length; i++) {\n dom.on(events[i], fireCallBack);\n }\n }\n }\n\n $.fn.animationEnd = function (callback) {\n __dealCssEvent.call(this, ['webkitAnimationEnd', 'animationend'], callback);\n return this;\n };\n\n function submitForm(doc, url, params) {\n var form = doc.createElement(\"form\");\n form.action = url;\n form.method = \"post\";\n form.style.display = \"none\";\n\n for (var x in params) {\n var ele = doc.createElement(\"input\");\n ele.type = \"hidden\";\n ele.name = x;\n ele.value = params[x];\n form.appendChild(ele);\n }\n\n doc.body.appendChild(form);\n form.submit();\n }\n\n // 检查是否有ipu-pages的结构\n function checkPages() {\n if (!hasPages) {\n pagesObj = $(\".ipu-pages\"); // pagesObj为空则进行jquery取值\n if (pagesObj.size() == 0) {\n pagesObj = $(\"<div class='ipu-pages'><div class='ipu-page ipu-show \" + zeroPageClass + \"' id='\" + pageIdPrefix + \"0'></div>\").appendTo(\"body\");\n }\n hasPages = true;\n }\n }\n\n // 站位页面\n function isZeroPage(page) {\n return $(page).hasClass(zeroPageClass);\n }\n\n var page = {};\n var hasPages = false;\n var maps = {};\n var pageNo = 1; // 编号0留给主页面或当前页面,或没有\n var pageIdPrefix = \"ipuPage-\";\n var pagesObj = null;\n var animateInClass = \"ipu-anim ipu-slideRightIn\";\n var animateOutClass = \"ipu-anim ipu-slideRightOut\";\n var eventName = \"ipuUIPageBack\";\n var zeroPageClass = 'ipu-page-zero'; // 占位页面,对于为当前页面\n var zeroPagesClass = 'ipu-pages-zero'; // 占位页面的特殊class,作用已忘记,应该是用来标记显示用\n\n /**\n * @private\n * @class page 单页面实现功能对象\n * 以iframe加载子页面的方式,页面后退(后退时,后退到a页面,所有在a页面后打开的页面全都关闭)\n * ipu框架在浏览器运行时,使用此对象实现与客户端运行类似的效果\n * 大致实现是当前页面进行处理,所有的后续页面加载都放在一个iframe中,所有页面按加载顺序排序,关闭或后退按页面打开的顺序处理\n */\n\n\n /**\n * 组件默认配置项\n *\n * @cfg {Object} defaultOption page组件默认配置项\n * @cfg {Window} defaultOption.target = window.parent 默认执行的窗口对象,子页面调用相关方法,默认都都是在parent窗口执行,需要指定此参数,如顶层父窗口\n * @cfg {Number} defaultOption.backIndex=-1 回退索引,大于0时,正序计算,小于0时,倒序计算,-1即为当页面的上一个页面\n * @cfg {Number} defaultOption.closeIndex 关闭页面索引,参数说明同上\n * @cfg {Object} defaultOption.params Json格式参数,POST方式打开页面时,使用此参数传递参数,暂不支持数组格式参数\n * @cfg {Boolean} defaultOption.animate=true 是否使用动画,打开或回退页面时有效参数\n * @cfg {Boolean} defaultOption.showLoading=true 是否显示加载提示,打开或回退页面时有效参数\n * @cfg {Boolean} defaultOption.loadingMessage='正在加载中' 是否显示加载提示,打开或回退页面时有效参数\n * @cfg defaultOption.data=null 回退页面时,传递给回退到的页面的参数,回退到的页面有设置监听函数时,监听函数可以接收此参数\n * @cfg {String} defaultOption.pageName='' 页面的名称,打开或回退页面时有效参数\n * @cfg {Number} defaultOption.pageMax='' 保留的最大页面数,大于2\n * @cfg {Function} defaultOption.callBack 方法执行结束时的回调函数\n */\n page.defaultOption = { // 那个窗口执行open,默认父窗口\n target: window.parent, // 默认执行父窗口,方法:all\n backIndex: -1, // 默认回退一页 方法:back\n closeIndex: -1, // 默认关闭最近一个页面 方法:close\n params: {}, // post的传参 方法:post\n animate: true, // 是否动画效果 方法:open post\n showLoading: true, // 是否显示加载消息 方法:open post\n loadingMessage: '正在加载中', // 方法:open post\n method: null, // 请求方式,内置参数,方法自己设置,用户不需要设置 方法:无\n minMessageTime: 500, // 最小显示加载时间,避免出现闪现的情况 方法:open post\n data: null, // 回退时,回传参数, 方法:back\n pageName: '', // 给打开的页面命名,以便根据此页面名称来切换页面 方法:open post back close\n pageMax: 6, // 允许的最大打开页面数\n callBack: function () { // 事件回调 方法:open post close back\n }\n };\n\n // 新增限制最大页面数\n page.limitPages = function () {\n var pageMax = this.defaultOption.pageMax - 2; //\n $(\".ipu-page.ipu-show\").prevAll(\".ipu-page:gt(\" + pageMax + \")\").remove();\n };\n\n // 当前页面加载,针对顶层父窗口\n page.openPage = function (url, option) {\n var newPage = null;\n var nowPageNo = pageIdPrefix + (pageNo++);\n maps[nowPageNo] = url;\n\n checkPages();\n\n if (option.showLoading) {\n ipu.showPreloader(option.loadingMessage, option.minMessageTime);\n }\n\n if (option.method == 'post') {\n newPage = $(\"<div class='ipu-page' id='\" + nowPageNo + \"' data-name='\" + option.pageName + \"'><iframe class='ipu-page-iframe'></iframe></div>\");\n } else {\n newPage = $(\"<div class='ipu-page' id='\" + nowPageNo + \"' data-name='\" + option.pageName + \"'><iframe class='ipu-page-iframe' src='\" + url + \"'></iframe></div>\");\n }\n\n var zeroPage = isZeroPage($(\".ipu-page:last\", pagesObj));\n var animatePage = newPage;\n if (zeroPage) {\n animatePage = pagesObj.addClass(zeroPagesClass);\n }\n\n function end() {\n if (option.showLoading) {\n ipu.hidePreloader();\n }\n\n if (option.animate) {\n console.log(\"--\" + nowPageNo);\n animatePage.removeClass(animateInClass);\n }\n\n newPage.siblings(\".ipu-show\").removeClass('ipu-show');\n if (option.callBack) {\n option.callBack();\n }\n\n // 新增限制最大页面数\n page.limitPages();\n }\n\n $(\".ipu-page-iframe\", newPage).one('load', function () {\n newPage.addClass(\"ipu-show\").width(); // 强制生效,否则可能出现页面闪现,无动画情况\n\n if (zeroPage) {\n animatePage.removeClass(zeroPagesClass);\n }\n if (option.animate) {\n animatePage.addClass(animateInClass).animationEnd(end);\n } else {\n end();\n }\n });\n\n newPage.appendTo(pagesObj);\n if (option.method == 'post') {\n var pageDoc = $(\".ipu-page-iframe\", newPage)[0].contentDocument;\n submitForm(pageDoc, url, option.params);\n }\n };\n\n // post方式加载页面\n page.postPage = function (url, option) {\n option.method = 'post';\n page.openPage(url, option);\n };\n\n // 当前页面后退,针对顶层父窗口\n page.backPage = function (option) {\n var backIndex = option.backIndex;\n var page = null;\n var nowPage = $(\".ipu-page.ipu-show\", pagesObj);\n\n if (option.pageName) {\n page = $(\".ipu-page[data-name='\" + option.pageName + \"']:first\", pagesObj);\n } else if (backIndex == 0) {\n page = $(\".ipu-page:first\", pagesObj);\n } else { // 越界的情况\n var prevPage = nowPage.prevAll(\".ipu-page\");\n if (backIndex < 0) {\n page = $(prevPage[-backIndex - 1]);\n } else {\n page = $(prevPage[prevPage.size() - backIndex]);\n }\n }\n\n var animatePage = nowPage;\n var zeroPage = isZeroPage(page);\n\n // 主页面模式时\n if (zeroPage) {\n animatePage = pagesObj;\n } else {\n page.addClass(\"ipu-show\"); //显示前一个\n }\n\n function end() {\n $(this).removeClass(animateOutClass);\n page.nextAll(\".ipu-page\").remove();\n\n var iframe = $(\".ipu-page-iframe\", page);\n var nowDoc;\n\n if (iframe.size() == 0) { // 找不到子窗口就当是返回了主页面,在当前窗口触发\n nowDoc = window.document;\n } else {\n nowDoc = iframe[0].contentDocument;\n }\n\n if (zeroPage) {\n pagesObj.addClass(zeroPagesClass);\n }\n\n var evt = nowDoc.createEvent('Event');\n evt.initEvent(eventName, true, true);\n if (option.data) {\n evt.data = option.data;\n }\n nowDoc.body.dispatchEvent(evt);\n if (option.callBack) {\n option.callBack();\n }\n }\n\n if (option.animate) {\n animatePage.addClass(animateOutClass).animationEnd(end);\n } else {\n end();\n }\n };\n\n // 往前关闭窗口\n page.closePage = function (option) {\n var closeIndex = option.closeIndex;\n var prevPage = $(\".ipu-page.ipu-show\", pagesObj).prevAll(\".ipu-page\");\n\n if (option.pageName) {\n closeIndex = $(\".ipu-page[data-name='\" + option.pageName + \"']:first\", pagesObj).index();\n } else if (closeIndex < 0) {\n closeIndex = -closeIndex - 1;\n } else {\n closeIndex = prevPage.size() - closeIndex;\n }\n\n $(prevPage[closeIndex]).remove();\n if (option.callBack) {\n option.callBack();\n }\n };\n\n /**\n * get请求的方式加载页面\n *\n * @param {String} url\n * @param {Object} option 回退参数,见{@link #cfg-defaultOption}\n */\n page.open = function (url, option) {\n option = $.extend({}, this.defaultOption, option);\n option.target.ipu.page.openPage(url, option);\n };\n\n /**\n * 使用post方式加载一个新页面\n *\n * @param {String} url 要打开的页面地址\n * @param {Object} option 回退参数,见{@link #cfg-defaultOption}\n */\n page.post = function (url, option) {\n option = $.extend({}, this.defaultOption, option);\n option.method = 'post';\n option.target.ipu.page.openPage(url, option);\n };\n\n /**\n * 回退到某个历史页面,可以根据pageName回退,也可根据backIndex回退,默认回退上一个页面\n *\n * @param {Object} option 回退参数,见{@link #cfg-defaultOption}\n */\n page.back = function (option) {\n option = $.extend({}, this.defaultOption, option);\n option.target.ipu.page.backPage(option);\n };\n\n /**\n * 回退到首页\n *\n * @param {Object} option 回退参数,见{@link #cfg-defaultOption}\n */\n page.backHome = function (option) {\n option = option || {};\n option.backIndex = 0;\n page.back(option);\n };\n\n // 子窗口,待确认\n page.close = function (option) {\n option = $.extend({}, this.defaultOption, option);\n option.target.ipu.page.closePage(option);\n };\n\n /**\n * 给页面增加一个监听,从其它页面回退到此页面,调用此函数,可以接收其它页面传来的数据\n *\n * @param {Function} back 监听函数\n * @param back.data 其它页面传过来的参数,推荐字符串或Json对象\n */\n page.onBack = function (back) {\n $(\"body\").on(eventName, function (e) {\n var data = e.originalEvent.data;\n back(data);\n });\n };\n\n // 提供一个关闭一群窗口的方法\n ipu.page = page;\n})(ipu || window, jQuery);\n\n// picker\n(function (ipu, $, Hammer) {\n var showItemSize = 9; // 显示的子项数量,\n var r = 90; // 计算旋转的圆半径,结果应该缩小,是为了r不要距离容器太近,是否不应该设置px,使用rem\n var itemAngle = 180 / showItemSize; // 每项对应的角度是 180/9 = 20\n var maxExceed = itemAngle; // 滚动时允许超出边界的最大角度,允许最多翻过一项\n // itemHeight = 40px;每项数据的高度设置 // 需要给出r=89是怎么计算出来的,是根据 40/2/Math.tan(40/2/180*Math.PI)=113,直接太大不好看\n\n\n function toRem(num) {\n return num / 100;\n }\n\n /**\n * @private\n * @class 选择器,被DtPicker和PopPicker使用,实现选择与滚动等基础功能\n *\n * @constructor 初始化方法\n * @param {String|DOM|JQueryObj} slt\n * @param {object} option 组件参数,默认配置见 {@link #cfg-defaultOption}\n */\n function Picker(slt, option) {\n this.el = $(slt)[0];\n this.option = $.extend({}, this.defaultOption, option);\n this._init();\n }\n\n /**\n * 组件默认配置项\n *\n * @cfg {Object} defaultOption=\n * @cfg {Boolean} defaultOption.listen=true 是否需要监听变化\n * @cfg {[Object]} defaultOption.data=[] 可选择项数组,每个项须有text属性\n * @cfg {String} defaultOption.data.text 子项展示文本\n * @cfg {Function} defaultOption.onChange=null 选择变化时的回调函数\n * @cfg {Object} defaultOption.onChange.sltItem 选中项\n * @cfg {Number} defaultOption.onChange.newIndex 新的选中项索引\n * @cfg {Number} defaultOption.onChange.oldIndex 旧的选中项索引\n * @cfg {Boolean} defaultOption.onChange.newData 是否为调用setItem()方法触发\n */\n Picker.prototype.defaultOption = {\n listen: true,\n data: [],\n onChange: null\n };\n\n Picker.prototype._init = function () {\n var self = this;\n this.wrap = $(\">ul\", this.el);\n this.index = null; // 选中项索引\n this.listen = !!this.option.listen;\n\n this.beginAngle = 0; // 开始角度\n this.beginExceed = this.beginAngle - maxExceed; // 最小角度值\n this.stopInertiaMove = false;\n this.lastAngle = null; // 保存滑动前的角度 // 当前滚动的角度\n\n // 如果是ios,则ul的旋转中心点,样式不同于android\n if (ipu.device.ios) {\n this.wrap.css(\"transform-origin\", \"center center \" + toRem(r) + \"rem\"); //如果是ios,要变更旋转的中心点\n }\n\n\n this.setItems(this.option.data);\n\n this.hammer = new Hammer.Manager(this.el);\n this.hammer.add(new Hammer.Pan({direction: Hammer.DIRECTION_VERTICAL, threshold: 5}));\n this.hammer.add(new Hammer.Press({threshold: 4})); //\n this.hammer.on(\"panstart panmove panend pancancel\", Hammer.bindFn(this._onPan, this));\n\n // 处理滚动中,用户点中某项,停止\n this.hammer.on(\"press pressup\", function (e) { // 如果用户点击了,是停止自动滚动\n if (this.empty) {\n return;\n }\n\n self.stopInertiaMove = true;\n if (e.type == 'pressup') {\n self.endScroll();\n }\n });\n };\n\n /**\n * 设置选择项\n *\n * @param {[Object]} data 设置项数组\n */\n Picker.prototype.setItems = function (data, textName) { // textNam字体暂不支持\n this.wrap.empty(); // 清空历史数据\n this.data = data = data || [];\n this.empty = data.length == 0; // 数据是否为空\n\n this.newData = true; // 是否为新设置数据标记\n var self = this;\n var lis = \"\";\n textName = textName || 'text';\n\n for (var i = 0, j = data.length; i < j; i++) {\n lis = lis + \"<li>\" + data[i][textName] + \"</li>\";\n }\n\n $(lis).appendTo(this.wrap);\n\n this.items = $(\">li\", this.wrap);\n this.itemsSize = this.items.size();\n\n this.endAngle = (this.empty ? 0 : this.itemsSize - 1) * itemAngle;\n this.endExceed = this.endAngle + maxExceed; // 最大旋转角度值\n\n // 初始化各子项角度\n this.items.each(function (i) {\n $(this).css({\n \"transform\": \"translateZ(\" + toRem(r) + \"rem) rotateX(-\" + (i * itemAngle) + \"deg)\",\n \"transform-origin\": \"center center -\" + toRem(r) + \"rem\"\n });\n $(this).click(function () {\n self.stopInertiaMove = true;\n self.setAngle(i * itemAngle, true);\n })\n });\n\n var newAngle;\n if (this.empty || this.index == null) {\n newAngle = 0;\n } else {\n if (this.index > this.itemsSize - 1) { // 取最大值\n newAngle = (this.itemsSize - 1) * itemAngle;\n } else {\n newAngle = this.index * itemAngle;\n }\n }\n this.setAngle(newAngle, true);\n };\n\n Picker.prototype._onPan = function (ev) {\n if (this.empty) {\n return;\n }\n\n //console.log(ev.deltaX + \"==\"+ ev.deltaY);\n if (ev.type == 'panstart') { // 好像一定要移动才有startg事件\n self.stopInertiaMove = true;\n this.lastAngle = this.angle;\n this.wrap.addClass(\"ipu-noanimate\"); // 移除动画\n this.stopInertiaMove = true; // 停止自动减速滚动\n\n } else if (ev.type == 'panmove') {\n var moveAngle = this.calcAngle(ev.deltaY);\n var newAngle = this.lastAngle - moveAngle; //最新的角度\n //console.log('=='+newAngle);\n // 一个可以转动的最小值和最大值过滤\n if (newAngle < this.beginExceed) {\n newAngle = this.beginExceed;\n }\n if (newAngle > this.endExceed) {\n newAngle = this.endExceed;\n }\n this.setAngle(newAngle);\n\n } else { // end or cancel事件\n // console.log('end or cancel:' + ev.type);\n var v = ev.overallVelocityY; // 滑动的速度\n var dir = v > 0 ? -1 : 1; //加速度方向\n var deceleration = dir * 0.0006 * -1;\n var duration = Math.abs(v / deceleration); // 速度消减至0所需时间\n var dist = v * duration / 2; //最终移动多少\n\n var startAngle = this.angle;\n var distAngle = -this.calcAngle(dist);\n // console.log(\"dist=\" + dist + \", distAngle\" + distAngle);\n\n //----\n var srcDistAngle = distAngle;\n if (startAngle + distAngle < this.beginExceed) {\n distAngle = this.beginExceed - startAngle;\n duration = duration * (distAngle / srcDistAngle) * 0.6;\n }\n if (startAngle + distAngle > this.endExceed) {\n distAngle = this.endExceed - startAngle;\n duration = duration * (distAngle / srcDistAngle) * 0.6;\n }\n\n if (distAngle == 0) {\n this.endScroll();\n return;\n }\n this.scrollDistAngle(startAngle, distAngle, duration);\n }\n };\n\n // 计算移动的角度,转动的角度,就是移动的距离对应相关圆周\n // 2*r*PI = 360, angle = 360*c/(2*r*PI)\n var ca = 360 / (2 * r * Math.PI);\n Picker.prototype.calcAngle = function (c) {\n return c * ca;\n };\n\n /**\n * 为组件设置新的滚动角度\n *\n * @param {Number} newAngle 新的滚动角度\n * @param {Boolean} endScroll 是否为最终滚动角度,为最终滚动角度时,若索引更新可以触发onChange的回调\n */\n Picker.prototype.setAngle = function (newAngle, endScroll) {\n this.angle = newAngle; // 存储最新值\n this.wrap.css(\"transform\", \"perspective(\" + toRem(1000) + \"rem) rotateY(0deg) rotateX(\" + newAngle + \"deg)\");\n this.calcItemVisable(newAngle);\n\n if (endScroll) {\n var index = newAngle / itemAngle;\n var oldIndex = this.index;\n this.index = this.empty ? null : index; // 这里可以做一个判断,如果是empty,则index值可以不改变\n\n // 这个地方要判断下,数据更新或索引更新都要触发\n if (oldIndex != index || this.newData) {\n if (this.option.onChange && this.listen) {\n this.option.onChange(this.getSelectedItem(), this.index, oldIndex, this.newData);\n }\n this.newData = false;\n }\n }\n };\n\n /**\n * 计算各子项滚动角度与新的滚动角度的值差异来决定显示的情况\n * 角度大于 90-(itemAngle/2)时,隐藏\n * 角度小于itemAngle/2表示最中心的项,显示并高亮\n * 其它值则表示此项为显示\n *\n * @param {Number} angle 新的滚动角度\n */\n Picker.prototype.calcItemVisable = function (angle) {\n this.items.each(function (index) {\n var difference = Math.abs(index * itemAngle - angle);\n\n if (difference < itemAngle / 2) {\n $(this).addClass(\"ipu-highlight ipu-visible\");\n } else if (difference >= (90 - itemAngle / 2)) { // 距离不能超过90度\n $(this).removeClass(\"ipu-highlight ipu-visible\");\n } else {\n $(this).addClass(\"ipu-visible\").removeClass(\"ipu-highlight\");\n }\n });\n };\n\n // 设置最后回归位置\n Picker.prototype.endScroll = function () {\n this.wrap.removeClass(\"ipu-noanimate\");\n var endAngle;\n\n if (this.angle < this.beginAngle) {\n endAngle = this.beginAngle;\n } else if (this.angle > this.endAngle) {\n endAngle = this.endAngle;\n } else {\n var index = parseInt((this.angle / itemAngle).toFixed(0));\n endAngle = (itemAngle * index);\n }\n\n this.setAngle(endAngle, true);\n };\n\n // 进行惯性滚动\n Picker.prototype.scrollDistAngle = function (startAngle, distAngle, duration) {\n var self = this;\n var nowTime = new Date().getTime();\n this.stopInertiaMove = false;\n duration = 1 * duration; // 滚动时长控制修改\n\n // hammer调用的惯性函数\n (function (nowTime, startAngle, distAngle, duration) {\n var frameInterval = 13;\n var stepCount = duration / frameInterval;\n var stepIndex = 0;\n\n (function inertiaMove() {\n if (self.stopInertiaMove) return;\n var newAngle = self.quartEaseOut(stepIndex, startAngle, distAngle, stepCount);\n self.setAngle(newAngle);\n stepIndex++;\n\n if (stepIndex > stepCount - 1 || newAngle < self.beginExceed || newAngle > self.endExceed) {\n self.endScroll();\n return;\n }\n\n setTimeout(inertiaMove, frameInterval);\n })();\n\n })(nowTime, startAngle, distAngle, duration);\n };\n\n /**\n * 设置是否监听触发onChange回调\n *\n * @param {Boolean} listen\n */\n Picker.prototype.setListen = function (listen) {\n this.listen = !!listen;\n };\n\n Picker.prototype.quartEaseOut = function (t, b, c, d) {\n return -c * ((t = t / d - 1) * t * t * t - 1) + b;\n };\n\n /**\n * 设置选中项,若子项的value属性为value,则设置该项为选中项\n *\n * @param value\n */\n Picker.prototype.setSelectedValue = function (value) {\n var self = this;\n for (var index in self.data) {\n var item = self.data[index];\n if (item.value == value) {\n self.setAngle(index * itemAngle, true);\n return;\n }\n }\n };\n\n /**\n * 获取选中的子项,若子项集为空时,返回空对象\n *\n * @returns {Object}\n */\n Picker.prototype.getSelectedItem = function () {\n return this.empty ? {} : this.data[this.index];\n };\n\n /**\n * 获取选中的子项的value属性\n * @returns\n */\n Picker.prototype.getSelectedValue = function () {\n return this.getSelectedItem().value;\n };\n\n /**\n * 返回选中项的text属性\n * @return {String}\n */\n Picker.prototype.getSelectedText = function () {\n return this.getSelectedItem().text;\n };\n\n /**\n * 获取选中项的索引,若子项集为空则返回null\n * @returns {Number}\n */\n Picker.prototype.getSelectedIndex = function () {\n return this.index;\n };\n\n ipu.Picker = Picker;\n\n})(ipu || window, jQuery, Hammer);\n\n// popPicker\n(function (ipu, $) {\n var Picker = ipu.Picker;\n\n /**\n * @class\n * 原生select的替代实现,适应数据较多或级联的情况\n *\n * @example\n // 配置项data的数据结构\n var data = [{text:'显示名称', value:''}...];\n\n // layer=1的数据结构\n var data-1 = [{text:'湖南', value:'HN'}, {text:'湖北', value:'HB'}];\n\n // layer=2时的数据结构,有额外data属性存放下一层级数据\n var data-1 = [{\n text:'湖南',value:'HN', data:[{text:'长沙', value:'CS'}, {text:'湘谭', value:'XT'}]\n },{\n text:'湖北',value:'HB', data:[{text:'武汉', value:'WH'}, {text:'天门', value:'TM'}]\n }\n ];\n\n *\n * @constructor 不能直接访问该类,调用{@link ipu#navBar ipu.popPicker(slt, option)}生成实例\n * @param {String|jqueryObj} slt\n * jquery选择器字符串或jquery对象,用来查找要被组件初始化化的dom\n * @param {Object} option 组件配置参数,默认配置见 {@link #cfg-defaultOption}\n */\n function PopPicker(option) {\n this.option = $.extend({}, this.defaultOption, option);\n if (!Picker) {\n Picker = ipu.Picker;\n }\n this._init();\n }\n\n PopPicker.prototype._init = function () {\n this.holder = $(this.option.template).appendTo(\"body\");\n var bodyHtml = $(\".ipu-poppicker-body\", this.holder);\n\n var layer = this.option.layer;\n var width = (100 / layer) + \"%\";\n this.pickers = new Array(layer);\n var self = this;\n var pickerHtml;\n this.mask = this.createMask();\n\n // 先初始化最底层picerk,再上面来\n for (var i = layer - 1; i >= 0; i--) {\n pickerHtml = $(this.option.pickerTemplate).prependTo(bodyHtml).css({width: width});\n\n this.pickers[i] = new Picker(pickerHtml, {\n onChange: (function (i) {\n return function (item) { // 更新底部的值\n if (i != layer - 1) {\n self.pickers[i + 1].setItems(item.data);\n }\n };\n })(i)\n });\n }\n\n $(\".ipu-poppicker-btn-ok\", this.holder).click(function () {\n var rs = self.getSelectItems();\n if (self.option.callBack(rs) !== false) {\n self.hide();\n }\n }).text(this.option.btns[1]);\n\n $(\".ipu-poppicker-btn-cancel\", this.holder).click(function () {\n self.hide();\n }).text(this.option.btns[0]);\n };\n\n /**\n * 组件默认配置项\n *\n * @cfg {Object} defaultOption\n * @cfg {String} defaultOption.template html结构\n * @cfg {String} defaultOption.pickerTemplate 内容dom选择器\n * @cfg {Object[]} defaultOption.data 选择项数据\n * @cfg {String} defaultOption.data.text 子项展示文本\n * @cfg {*} defaultOption.data.value 子项值\n * @cfg {Object[]} defaultOption.data.data 有更多层级时,此属性存放下一层级的数据\n * @cfg {Number} defaultOption.layer=1 数据层数\n * @cfg {String[]} defaultOption.btns=['取消', '确认'] 按钮文本\n * @cfg {Function} defaultOption.callBack=null 回调函数\n */\n PopPicker.prototype.defaultOption = {\n template: '<div class=\"ipu-poppicker\">'\n + '<div class=\"ipu-poppicker-header\">'\n + '<button class=\"ipu-btn ipu-btn-s ipu-poppicker-btn-cancel\">取消</button>'\n + '<button class=\"ipu-btn ipu-btn-s ipu-poppicker-btn-ok\">确定</button>'\n + '</div>'\n + '<div class=\"ipu-poppicker-body\">'\n + '</div>'\n + '</div>',\n pickerTemplate: '<div class=\"ipu-picker\">'\n + '<div class=\"ipu-picker-selectbox\"></div>'\n + '<ul></ul>'\n + '</div>',\n data: [], // 数据\n layer: 1, // 数据层级\n btns: ['取消', '确认'],\n callBack: function () { // 选择数据时的回调函数\n\n }\n };\n\n /**\n * 设置选择项数据\n *\n * @param{[Object]} data 选择项数组\n * @param {String} data.text 每个选择项的文本\n * @param {[Object]} data.data 如果有多层选择的话,应该有一个data属性\n */\n PopPicker.prototype.setData = function (data) {\n this.pickers[0].setItems(data);\n };\n\n /**\n * 显示选择器\n *\n * @param callBack\n */\n PopPicker.prototype.show = function (callBack) {\n if (callBack) {\n this.option.callBack = callBack;\n }\n this.mask.show();\n this.holder.addClass(\"ipu-current\");\n };\n\n /**\n * 隐藏选择器\n */\n PopPicker.prototype.hide = function () {\n this.mask.close();\n this.holder.removeClass(\"ipu-current\");\n };\n\n /**\n * 获取用户选择的项,如果配置项layer为1,则直接返回选择项,\n * 否则返回一个数组返回每层选中的项\n *\n */\n PopPicker.prototype.getSelectItems = function () {\n if (this.option.layer == 1) {\n return this.pickers[0].getSelectedItem();\n } else {\n var rs = [];\n for (var i = 0; i < this.option.layer; i++) {\n rs.push(this.pickers[i].getSelectedItem());\n }\n return rs;\n }\n };\n\n // 应该移除callback参数,提取出业成一个工具方法\n PopPicker.prototype.createMask = function (callback) {\n var self = this;\n var element = document.createElement('div');\n element.classList.add(\"ipu-picker-backup\");\n //element.addEventListener($.EVENT_MOVE, $.preventDefault);\n element.addEventListener('click', function () {\n self.hide();\n });\n var mask = [element];\n mask._show = false;\n mask.show = function () {\n mask._show = true;\n element.setAttribute('style', 'opacity:1');\n document.body.appendChild(element);\n return mask;\n };\n mask._remove = function () {\n if (mask._show) {\n mask._show = false;\n element.setAttribute('style', 'opacity:0');\n setTimeout(function () {\n var body = document.body;\n element.parentNode === body && body.removeChild(element);\n }, 350);\n }\n return mask;\n };\n mask.close = function () {\n if (mask._show) {\n if (callback) {\n if (callback() !== false) {\n mask._remove();\n }\n } else {\n mask._remove();\n }\n }\n };\n return mask;\n };\n\n /**\n * @member ipu\n * 生成PopPicker实例,参数信息见{@link PopPicker#method-constructor}\n *\n * @param {String} slt\n * @param {Object} option\n * @returns {PopPicker}\n */\n ipu.popPicker = function (option) {\n return new PopPicker(option);\n };\n\n})(ipu || window, jQuery);\n\n(function (ipu, $) {\n\n /**\n * @class\n * 进度条\n *\n * @example\n * <!-- 组件html -->\n * <div class=\"ipu-ipu-progress \">\n * <span class=\"ipu-progressbar\"></span>\n * </div>\n *\n *\n * @constructor 不能直接访问该类,调用 {@link ipu#progressBar}生成实例\n * @param {String|jqueryObj} slt\n * jquery选择器字符串或jquery对象,用来查找要被组件初始化化的dom\n * @param {Object} option 组件配置参数,默认配置见 {@link #cfg-defaultOption}\n */\n function ProgressBar(id, option) {\n this.id = id;\n this.level = option.level;\n this.progress = option.progress;\n this.progressBar = $(id).eq(0);\n\n if (option.progress != null) {\n this.setProgress(this.progress);\n }\n if (option.level != null) {\n this.setLevel(this.level);\n }\n }\n\n /**\n * @cfg defaultOption 刷新组件默认配置\n * @cfg {default|warning|highlight|success} defaultOption.level='default' 级别,显示颜色\n * @cfg {Number} defaultOption.progress=null 当前进度百分比\n *\n */\n\n /**\n * 设置百分进度\n *\n * @param {Number} pro\n */\n ProgressBar.prototype.setProgress = function (pro) {\n if (pro < 0 || pro > 100) return;\n\n $(this.progressBar.find(\".ipu-progressbar\")).css(\"transform\", \"translate3d(\" + (-(100 - pro)) + \"%, 0px, 0px)\");\n this.progress = pro;\n };\n\n /**\n * 获取百分进度\n *\n * @returns {Number|*}\n */\n ProgressBar.prototype.getProgress = function () {\n return this.progress;\n };\n\n /**\n * 设置进度条级别\n *\n * @param {default | success | highlight | warning} level\n */\n ProgressBar.prototype.setLevel = function (level) {\n if (level == \"default\") {\n $(this.progressBar).removeClass(\"ipu-progressbar-success ipu-progressbar-hightlight ipu-progressbar-warning\");\n $(this.progressBar).addClass(\"ipu-progress\");\n } else if (level == \"success\") {\n $(this.progressBar).removeClass(\"ipu-progressbar-highlight ipu-progressbar-warning\");\n $(this.progressBar).addClass(\"ipu-progressbar-success\");\n } else if (level == \"highlight\") {\n $(this.progressBar).removeClass(\"ipu-progressbar-success ipu-progressbar-warning\");\n $(this.progressBar).addClass(\"ipu-progressbar-highlight\");\n } else if (level == \"warning\") {\n $(this.progressBar).removeClass(\"ipu-progressbar-success ipu-progressbar-highlight\");\n $(this.progressBar).addClass(\"ipu-progressbar-warning\");\n }\n };\n\n /**\n * @member ipu\n * 生成PopPicker实例,参数信息见{@link ProgressBar#method-constructor}\n *\n * @param {String} slt\n * @param {Object} option\n * @returns {ProgressBar}\n */\n ipu.progressBar = function (slt, option) {\n return new ProgressBar(slt, option);\n };\n})(ipu || window, jQuery);\n\n// 设置上下条件长度,或计算函数\n// 处理resize的问题,用户主动调用refresh??\n// 底部启用或停用时,应该刷新组件iscroll高度\n// 顶部正在加载时,自动停止底端加载状态,停用底部加载,停用底部加载时,可以不隐藏,变性成显示不见,或者隐藏,然后修改iscroll参数\n\n(function (ipu, $, iScroll) {\n /**\n * @class\n * 通过IScroll.js实现上拉下拉加载\n *\n * @example\n * <!-- 组件html结构,最外层div应有一个固定的高度,会在此元素上初始化iScroll -->\n * <div>\n * <div class=\"ipu-refresh-wrapper\">\n * <!-- 此处组件初始化后,会添加上拉html -->\n * <div class=\"refresh-content\">\n * 内容区...\n * </div>\n * <!-- 此处组件初始化后,会添加下拉html -->\n * </div>\n * </div>\n *\n * @uses IScroll.js\n *\n * @constructor 不能直接访问该类,调用ipu.refresh(slt, option)生成实例\n * @param {String|JqueryObj|Dom} slt\n * jquery选择器字符串或jquery对象,用来查找要被组件初始化化的dom\n * @param {Object} option\n * 组件参数\n */\n function Refresh(slt, option) {\n this.option = $.extend({}, this.defaultOption, option);\n this.el = $(slt).get(0);\n this._initBottomAndTop();\n var me = this;\n\n this.iScrollOption = {\n onScrollMove: function (e) {\n if (me.topEnable && !me.topLoading) { // 顶部是松手才加载\n if (this.y >= me.topPullOffset && !me.topEl.hasClass('ipu-refresh-toload')) { // 达到刷新距离,更新显示状态\n me.topEl.addClass('ipu-refresh-toload');\n } else if (this.y < me.topPullOffset && me.topEl.hasClass('ipu-refresh-toload')) { // 从达到刷新距离更新为未达到距离,更新显示状态\n me.topEl.removeClass('ipu-refresh-toload');\n }\n }\n\n me._checkBottomLoading(); // 底部加载条件和顶部条件不一样,只要滚动离底部一定高度就开始加载\n me.goTop = this.y > me.topPullOffset; // 记录是否位于顶部位置,以便刷新后可以回到此位置\n },\n onBeforeScrollEnd: function () { // 一定是用户拖动触发,在滚动结束前应该触发\n me._checkTopLoading();\n me._checkBottomLoading();\n },\n onScrollEnd: function () { // 这个事件可能由非用户拖动时触发,可能是拖动惯性导致,所有顶部不应该处理,但顶部不管是否惯性,位置条件满足即触发\n if (me.topLoading && this.y < this.minScrollY && me.goTop) {\n me.iScroll.scrollTo(0, this.minScrollY, 0);\n }\n me._checkBottomLoading(); // 在beforend执行还不够,还在要end执行\n },\n onRefresh: function () { // 刷新时,若顶部加载还在进行,且当前显示的顶部加载,则继续显示,否则刷新后会消失顶部加载,这里代码没有考虑重用了,应该可以做一步提取\n if (me.topLoading) { // 如果顶部在加载,则刷新的时候,设置最小顶部距离,显示顶部加载状态\n this.minScrollY = this.minScrollY + me.topPullOffset;\n }\n }\n };\n\n this.iScrollOption = $.extend({}, this.option.iScrollOption, this.iScrollOption);\n this.iScroll = new iScroll(this.el, this.iScrollOption);\n this._checkContentLoading();\n }\n\n /**\n * @cfg defaultOption 刷新组件默认配置\n * @cfg {Function} defaultOption.bottomLoadFun=null 上拉时,触发底加载的响应函数\n * @cfg {Function} defaultOption.topLoadFun=null 下拉时,触发顶部加载的响应函数\n * @cfg {Boolean} defaultOption.initEnableTop=true 初始化时,是否启用顶部加载功能\n * @cfg {Boolean} defaultOption.initEnableBottom=true 初始化时,是否启用底部加载功能\n * @cfg {String} defaultOption.bottomLoadHtml=... 底部加载时显示的html片段,不建议变动\n * @cfg {String} defaultOption.topLoadHtml=... 顶部加载时显示的html片段,不建议变动\n * @cfg {Number} defaultOption.bottomAddLen=0 距离底部多远时,触发底部加载\n * @cfg {Object} defaultOption.iScrollOption={} 上下拉使用的是IScroll组件,通过此参数配置IScroll初始化的参数\n *\n */\n Refresh.prototype.defaultOption = {\n bottomLoadFun: null, // 底部加载处理函数\n topLoadFun: null, // 顶部加载处理函数\n initEnableTop: true, // 初始时启用刷新,有时用户并不想启用\n initEnableBottom: true, // 初始时启用加载更多,用时用户并不想启用\n bottomLoadHtml: '<div class=\"ipu-refresh-bottom\"><span class=\"ipu-refresh-loading\"></span></div>', // 默认底部加载显示内容\n topLoadHtml: '<div class=\"ipu-refresh-top\"><span class=\"ipu-refresh-loading\"></span><div class=\"ipu-refresh-arrow\"></div></div>',\n // 默认顶部加载显示内容,最上层节点class有下面三个阶段变化\n // 默认阶段,不是顶部加载状态时,且拖动时未达到加载距离,无特殊class,移除ipu-refresh-top-loading\n // 拖动达到加载距离,则增加class:ipu-refresh-toload\n // 加载中,则增加class:ipu-refresh-top-loading,移除class:ipu-refresh-toload\n bottomAddLen: 0, // 底部提前加载距离,单位px\n iScrollOption: {} // 主要是用来接收外面一些函数,不能传递回调的相关函数如refresh,也可在本地函数调用完后,再调用参数的函数,不推荐\n };\n\n Refresh.prototype._initBottomAndTop = function () {\n this.scrollEl = $(\">.ipu-refresh-wrapper\", this.el);\n this.bottomEl = $(this.option.bottomLoadHtml).appendTo(this.scrollEl);\n this.topEl = $(this.option.topLoadHtml).prependTo(this.scrollEl);\n\n this.topPullOffset = this.topEl.outerHeight();\n this.bottomPullOffset = this.bottomEl.outerHeight() + this.option.bottomAddLen; // 增加100;最好配一个额外参数\n\n /** @property {Boolean} 顶部是否加载中 */\n this.topLoading = false; // 顶部正在载加载\n\n /** @property {Boolean} 底部是否加载中 */\n this.bottomLoading = false; // 底部正在加载\n\n /** @property {Boolean} 底部是否可加载 */\n this.bottomEnable = this.option.initEnableBottom && !!this.option.bottomLoadFun;\n\n /** @property {Boolean} 顶部是否可加载 */\n this.topEnable = this.option.initEnableTop && !!this.option.topLoadFun;\n\n this.goTop = false; // 用来处理,因为iScroll使用momentum(惯性), 导致有时顶部显示不正确问题,true表示顶部显示加载条\n\n this.enableBottom(this.bottomEnable);\n this.enableTop(this.topEnable);\n };\n\n // 检查是否需要底部加载\n Refresh.prototype._checkBottomLoading = function () {\n if (this.bottomEnable) {\n if (this.iScroll.y < this.iScroll.maxScrollY + this.bottomPullOffset) {\n this._startBottomLoading();\n }\n }\n };\n\n Refresh.prototype._checkTopLoading = function () {\n if (this.topEnable) {\n if (this.topEl.hasClass('ipu-refresh-toload')) {\n this._startTopLoading();\n }\n }\n };\n\n // 检查内容是否超出容器高度,未超出时,自动调用底部加载\n Refresh.prototype._checkContentLoading = function () {\n if (this.bottomEnable) {\n if (this.iScroll.maxScrollY >= -this.bottomPullOffset) { // 此处要计算底端的高度\n this._startBottomLoading();\n }\n }\n };\n\n // 开始底部加载\n Refresh.prototype._startBottomLoading = function () {\n if (!this.bottomLoading) {\n this.bottomLoading = true;\n this.option.bottomLoadFun(); // 刷新当前索引加载更多的数据\n }\n };\n\n // 开始顶部加载\n Refresh.prototype._startTopLoading = function () {\n if (!this.topLoading) {\n this.topLoading = true;\n this.topEl.removeClass('ipu-refresh-toload').addClass('ipu-refresh-top-loading');\n this.iScroll.minScrollY = this.iScroll.minScrollY + this.topPullOffset;\n this.option.topLoadFun(); // 刷新当前索引加载更多的数据\n }\n };\n\n /**\n * 结束底部加载,defaultOption.bottomLoadFun中处理完加载后,最后调用此方法\n */\n Refresh.prototype.endBottomLoading = function () {\n this.bottomLoading = false;\n this.refresh();\n };\n\n /**\n * 结束顶部加载,defaultOption.topLoadFun中处理完加载后,最后调用此方法\n */\n Refresh.prototype.endTopLoading = function () {\n this.topEl.removeClass('ipu-refresh-top-loading');\n this.topLoading = false;\n // this.iScroll.scrollTo(0, 0); // 刷新加载则应该回到顶部,待测试确认\n this.refresh();\n };\n\n /**\n * 是否启动顶部加载功能\n *\n * @param {Boolean} enable\n */\n Refresh.prototype.enableTop = function (enable) {\n this.topEnable = enable;\n if (enable) {\n this.topEl.show();\n } else {\n this.topEl.hide();\n }\n };\n\n /**\n * 是否启用底部加载功能\n *\n * @param {Boolean} enable\n */\n Refresh.prototype.enableBottom = function (enable) {\n this.bottomEnable = enable;\n if (enable) {\n this.bottomEl.show();\n } else {\n this.bottomEl.hide();\n }\n };\n\n /**\n * 在内容发生变化时,但是又不是因为顶部加载或底部加载导致的,此时调用此方法刷新IScroll\n */\n Refresh.prototype.refresh = function () {\n this.iScroll.refresh();\n this._checkContentLoading();\n };\n\n\n /**\n * @member ipu\n * 生成PopPicker实例,参数信息见{@link Refresh#method-constructor}\n *\n * @param {String} slt\n * @param {Object} option\n * @returns {Refresh}\n */\n ipu.refresh = function (slt, optoins) {\n return new Refresh(slt, optoins);\n };\n\n})(ipu || window, jQuery, iScroll);\n\n// Tab\n(function (ipu, $) {\n\n /**\n * @class\n * tab切换组件功能实现\n *\n * @example\n * <!-- html结构 -->\n * <div class=\"ipu-tab\"> <!-- 如果class中添加 ipu-tab-fixed,则可固定头部,此时需要父元素的高度是确定的 -->\n * <ul class=\"ipu-tab-title ipu-tab-title-link\"> <!-- 页头有 ipu-tab-title-link 和 ipu-tab-title-button两种样式 -->\n * <li>热门推荐</li>\n * <li class=\"ipu-current\">全部表情</li> <!-- class为ipu-current为默认选中项 -->\n * <li>表情</li>\n * <li>表情</li>\n * </ul>\n * <div class=\"ipu-tab-body\">\n * <ul class=\"ipu-tab-body-wrapper\">\n * <li>自定义内容</li>\n * <li class=\"\">选项2内容</li>\n * <li class=\"\">选项3内容</li>\n * <li class=\"\">选项4内容</li>\n * </ul>\n * </div>\n * </div>\n *\n *\n * @constructor 不能直接访问该类,调用ipu.tab(slt, option)生成实例\n * @param {string|jqueryObj} slt\n * jquery选择器字符串或jquery对象,用来查找要被组件初始化化的dom\n * @param {object} option\n * 组件参数\n */\n function Tab(slt, option) {\n this.el = $(slt).get(0);\n this.titleItems = $(\".ipu-tab-title:first>li\", this.el);\n this.bodyWrapper = $(\".ipu-tab-body-wrapper:first\", this.el);\n this.contentItems = $(\">li\", this.bodyWrapper);\n\n this.option = $.extend({}, this.defaultOption, option);\n this.itemSize = this.contentItems.size();\n this.fixed = $(this.el).is(\".ipu-tab-fixed\"); // 是否为固定高度的\n\n var that = this;\n this.titleItems.each(function (index) {\n $(this).click(function () {\n that.show(index);\n });\n });\n\n var index = this.titleItems.filter(\".ipu-current\").index();\n if (index == -1) {\n index = 0;\n }\n\n this.show(index);\n }\n\n /**\n * 默认配置项\n * @cfg defaultOption = { callBack: function (index) {}};\n * @cfg defaultOption.callBack 切换tab项时的回调函数,参数为显示的项索引\n */\n Tab.prototype.defaultOption = {\n callBack: function (index) {\n }\n };\n\n /**\n * 显示第几项内容\n * @param {number} index 要显示的项索引\n */\n Tab.prototype.show = function (index) {\n if (this.fixed) {\n var move = -index * 100 + \"%\";\n this.bodyWrapper.css(\"transform\", \"translate3d(\" + move + \", 0, 0)\");\n }\n this.contentItems.eq(index).addClass(\"ipu-current\").siblings().removeClass(\"ipu-current\");\n this.titleItems.eq(index).addClass(\"ipu-current\").siblings().removeClass(\"ipu-current\");\n this._end(index);\n };\n\n Tab.prototype._end = function (index) {\n this.lastIndex = this.currentIndex;\n this.currentIndex = index;\n\n if (this.option.callBack) {\n this.option.callBack(index, this.lastIndex);\n }\n };\n\n ipu.tab = function (slt, option) {\n return new Tab(slt, option);\n };\n})(ipu || window, jQuery);\n\n\n\n // 初始化代码\n jQuery(function () {\n // 添加一个touchstart空函数,让:active样式可以在ios上生效\n // 新版默认不需要事件好像也可生效\n jQuery(\"body\").on(\"touchstart\",function (e) {});\n\n // 处理ios点击延迟问题\n FastClick.attach(document.body);\n });\n\n return ipu;\n }\n\n // todo:可以添加一个和其它库的适配处理,\n // 这里假设第三方库,jquery,iScroll,Hammer的史称已经固定\n if ( typeof define === \"function\" && define.amd ) {\n define(['jquery', 'iScroll', 'Hammer', 'FastClick'], function (jQuery, iScroll, Hammer, FastClick) {\n return window.ipu = setup(jQuery, iScroll, Hammer, FastClick);\n });\n } else {\n window.ipu = setup(window.jQuery, window.iScroll, window.Hammer, window.FastClick);\n }\n})();\n\n//# sourceMappingURL=ipu.js.map\n"]}
|
1
|
{"version":3,"sources":["ipu.js"],"names":["setup","jQuery","iScroll","Hammer","FastClick","ipu","version","$","getOriginalEvent","e","originalEvent","getXY","x","touches","pageX","clientX","y","pageY","clientY","active","options","defaultOptions","distanceAllow","displayDelay","hideDelay","eventName","activeClass","getHandleNode","node","findHander","inNode","eventHandlers","_data","data","thisNode","each","index","handler","selector","objs","nodeArray","tIndex","tNode","is","distNode","nodeType","parentNode","push","hasTouch","window","START_EVENT","MOVE_EVENT","END_EVENT","CANCEL_EVENT","removeClass","dom","force","timeOutID","clearTimeout","removeActive","tapEl","setTimeout","startXY","document","body","bind","target","addClass","xy","Math","abs","setOptions","opts","this","extend","iscroll","Carousel","slt","option","defaultOption","el","eq","autoPlay","hasIndicator","indicator","callBack","currentIndex","_init","play","prototype","duration","wrapper","carouselItems","size","that","activeIndex","filter","_addIndicator","resize","refresh","scrollOpt","snap","momentum","scrollX","scrollY","hScrollbar","onScrollStart","_pause","onTouchEnd","onScrollEnd","_end","get","show","stop","timeoutId","prev","next","time","scrollToPage","_play","currPageX","indicatorIndexs","siblings","html","i","appendTo","destroy","carousel","device","classNames","ua","navigator","userAgent","android","match","ipad","ipod","iphone","ios","androidChrome","os","osVersion","toLowerCase","indexOf","replace","split","pixelRatio","devicePixelRatio","floor","major","parseInt","wx","test","classPrev","length","join","DtPicker","Picker","defaultPickerDate","Date","template","buttons","labels","type","customData","hasClear","beginDate","endDate","self","mask","createMask","_picker","holder","ui","picker","ok","cancel","clear","listen","h","onChange","item","beginMonth","endMonth","_createMinutes","d","_createHours","m","_createDay","_createMonth","_create","_setLabels","_setButtons","attr","_setSelectedValue","value","getSelected","selected","getSelectedItem","toString","text","getFullYear","getMonth","getDate","getHours","getMinutes","parsedValue","_parseSetValue","setListen","setSelectedValue","isLeapYear","year","_inArray","array","_item","getDayNum","month","_fill","num","_isBeginYear","beginYear","getSelectedValue","_isBeginMonth","_isBeginDay","beginDay","_isBeginHours","beginHours","_isEndYear","endYear","_isEndMonth","_isEndDay","endDay","_isEndHours","endHours","_createYear","yArray","yBegin","yEnd","setItems","mArray","maxMonth","val","dArray","maxDay","hArray","maxHours","iArray","beginMinutes","maxMinutes","endMinutes","label","innerText","hide","click","clickCall","now","rs","parts","j","setDateRange","setBeginDate","date","setEndDate","dispose","removeChild","name","disposed","sltDate","call","close","callback","element","createElement","classList","add","addEventListener","_show","setAttribute","appendChild","_remove","dtPicker","HammerCarousel","loop","clickBack","itemSize","showItemSize","carouselItemWides","moveLen","cloneItem","slice","clone","hammer","Manager","Pan","direction","DIRECTION_HORIZONTAL","threshold","on","bindFn","_onPan","_sizeCount","width","wrapperWidth","outerWidth","itemWidth","mostSize","position","left","_move","move","displayMoveLen","css","animate","toggleClass","ev","delta","deltaX","intValue","decimal","hammerCarousel","__dealCssEvent","eventNameArr","fireCallBack","events","off","handleClicks","clicked","hasClass","defaults","modalCloseByOutside","closeModal","actionsCloseByOutside","popupCloseByOutside","fn","transitionEnd","_modalTemplateTempDiv","modalTitle","modalStack","modalButtonOk","modalButtonCancel","modalPreloaderTitle","modalContainer","modalStackClearQueue","shift","modal","params","buttonsHTML","bold","extraClass","titleHTML","title","textHTML","afterTextHTML","afterText","noButtons","verticalButtons","modalHTML","innerHTML","children","append","find","onClick","openModal","alert","callbackOk","arguments","undefined","confirm","callbackCancel","prompt","minLoad","loadOverTime","loadEnd","loadTimeOut","showPreloader","minTime","hidePreloader","preloaderModal","showIndicator","hideIndicator","remove","actions","groupSelector","buttonSelector","isArray","button","buttonClass","color","bg","disabled","groups","groupIndex","clickTarget","buttonIndex","buttonParams","toast","msg","extraclass","$toast","cb","isModal","isNotToast","isPopup","isLoginScreen","isPickerModal","isToast","marginTop","round","outerHeight","marginLeft","overlay","clientLeft","trigger","removeOnClose","NavBar","content","contentSlt","nav","contents","navs","me","lastIndex","navBar","submitForm","doc","url","form","action","method","style","display","ele","submit","checkPages","hasPages","pagesObj","zeroPageClass","pageIdPrefix","isZeroPage","page","animationEnd","maps","pageNo","animateInClass","animateOutClass","zeroPagesClass","parent","backIndex","closeIndex","showLoading","loadingMessage","minMessageTime","pageName","pageMax","limitPages","prevAll","openPage","end","console","log","nowPageNo","animatePage","newPage","zeroPage","one","pageDoc","contentDocument","postPage","backPage","nextAll","nowDoc","iframe","evt","createEvent","initEvent","dispatchEvent","nowPage","prevPage","closePage","open","post","back","backHome","onBack","toRem","r","itemAngle","maxExceed","wrap","beginAngle","beginExceed","stopInertiaMove","lastAngle","DIRECTION_VERTICAL","Press","empty","endScroll","textName","newData","lis","items","itemsSize","endAngle","endExceed","transform","transform-origin","setAngle","newAngle","angle","moveAngle","calcAngle","deltaY","v","overallVelocityY","dir","deceleration","dist","startAngle","distAngle","srcDistAngle","scrollDistAngle","ca","PI","c","calcItemVisable","oldIndex","difference","toFixed","nowTime","getTime","frameInterval","stepCount","stepIndex","inertiaMove","quartEaseOut","t","b","getSelectedText","getSelectedIndex","PopPicker","bodyHtml","layer","pickers","Array","pickerHtml","pickerTemplate","prependTo","getSelectItems","btns","setData","popPicker","ProgressBar","id","level","progress","progressBar","setProgress","setLevel","pro","getProgress","Refresh","_initBottomAndTop","iScrollOption","vScrollbar","onScrollMove","topEnable","topLoading","topPullOffset","topEl","_checkBottomLoading","goTop","onBeforeScrollEnd","_checkTopLoading","minScrollY","scrollTo","onRefresh","_checkContentLoading","bottomLoadFun","topLoadFun","initEnableTop","initEnableBottom","bottomLoadHtml","topLoadHtml","bottomAddLen","scrollEl","bottomEl","bottomPullOffset","bottomLoading","bottomEnable","enableBottom","enableTop","maxScrollY","_startBottomLoading","_startTopLoading","endBottomLoading","endTopLoading","enable","optoins","Tab","titleItems","bodyWrapper","contentItems","fixed","tab","attach","define","amd"],"mappings":"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","file":"ipu.min.js","sourcesContent":["(function () {\r\n function setup(jQuery, iScroll, Hammer, FastClick) {\r\n\r\n /**\r\n * @class ipu UI的主对象,通过此对象实例UI组件\r\n *\r\n */\r\n\r\n var ipu = {\r\n version: '0.2.1'\r\n };\r\n\n// tap点击效果处理,只针对jquery上面的click事件,依赖touch事件\r\n(function (ipu, $) {\r\n var active = {};\r\n\r\n var options = defaultOptions = {\r\n distanceAllow: 10, // 最大移动距离,超过移除效果\r\n displayDelay: 100, // 延时显示时间,以防止是滚动操作\r\n hideDelay: 120, // 隐藏延时时间\r\n eventName: 'click', // 事件处理是click\r\n activeClass: 'ipu-active', // 激活时的class\r\n getHandleNode: function (node) { // 找到最先一级处理此click事件的元素\r\n if (!node || !node.nodeType) return;\r\n\r\n var distNode = null;\r\n var nodeArray = [];\r\n\r\n // 还有其它情形考虑,如a标签的跳转,或在原生元素添加事件属性的\r\n function findHander(inNode) {\r\n // 此方法适用于jquery, 1.12.4, 2.2.4, 3.2.1版本,_data方法以后可能会被移除。$.data是一些老版本写法\r\n var eventHandlers = ($._data || $.data)(inNode, 'events');\r\n\r\n if (eventHandlers) {\r\n eventHandlers = eventHandlers[options.eventName];\r\n }\r\n\r\n if (!eventHandlers) {\r\n return;\r\n }\r\n\r\n var thisNode = false;\r\n $.each(eventHandlers, function (index, handler) {\r\n if (handler.selector) {\r\n var objs = $(handler.selector, inNode);\r\n $.each(nodeArray, function (tIndex, tNode) {\r\n if (objs.is(tNode)) {\r\n distNode = tNode;\r\n return false;\r\n }\r\n });\r\n\r\n if (distNode) {\r\n return false; //\r\n }\r\n } else {\r\n thisNode = true; // 保存distNode,有可能有子节点满足条件,所以只保存此值为默认值\r\n }\r\n });\r\n\r\n if (thisNode && distNode == null) { // 如果没在子节点找到click事件,而当前节点又有click事件,就使用当前节点\r\n distNode = inNode;\r\n }\r\n\r\n return distNode;\r\n }\r\n\r\n while (!(\"tagName\" in node) || !findHander(node)) {\r\n if (!node.parentNode || node.parentNode.nodeType != 1) {\r\n break;\r\n }\r\n nodeArray.push(node);\r\n node = node.parentNode;\r\n }\r\n\r\n return distNode;\r\n }\r\n };\r\n\r\n function getOriginalEvent(e) {\r\n return e.originalEvent || e;\r\n }\r\n\r\n function getXY(e) {\r\n var x = e.touches ? e.touches[0].pageX : e.clientX;\r\n var y = e.touches ? e.touches[0].pageY : e.clientY;\r\n return [x, y];\r\n }\r\n\r\n //根据不同浏览器获取不同原生事件event\r\n var hasTouch = \"ontouchstart\" in window,\r\n START_EVENT = hasTouch ? 'touchstart' : 'mousedown',\r\n MOVE_EVENT = hasTouch ? 'touchmove' : 'mousemove',\r\n END_EVENT = hasTouch ? 'touchend' : 'mouseup',\r\n CANCEL_EVENT = hasTouch ? 'touchcancel' : '';\r\n\r\n $(function () {\r\n var startXY, tapEl, timeOutID;\r\n var dom = document.body;\r\n\r\n // force为false的时候,不用管timeOutID,在老的timeOutID未移除的情况下,有可能又产生了新的,\r\n // 导致else代码未被执行,导致老的点击元素class未被移除\r\n function removeClass(dom, force) {\r\n if (force && timeOutID) {\r\n window.clearTimeout(timeOutID);\r\n } else {\r\n $(dom).removeClass(options.activeClass);\r\n }\r\n }\r\n\r\n function removeActive(force) {\r\n if (force) {\r\n removeClass(tapEl, force);\r\n } else {\r\n window.setTimeout(removeClass, options.hideDelay, tapEl, force);\r\n }\r\n startXY = null;\r\n tapEl = null;\r\n }\r\n\r\n $(dom).bind(START_EVENT, function (e) {\r\n if (tapEl) { // 多点接触时处理\r\n removeActive(true);\r\n return;\r\n }\r\n\r\n e = getOriginalEvent(e);\r\n startXY = getXY(e);\r\n tapEl = options.getHandleNode(e.target);\r\n\r\n if (tapEl) {\r\n timeOutID = window.setTimeout(function (dom) {\r\n timeOutID = null;\r\n $(dom).addClass(options.activeClass);\r\n }, options.displayDelay, tapEl);\r\n }\r\n });\r\n\r\n $(dom).bind(MOVE_EVENT, function (e) {\r\n if (!tapEl) {\r\n return;\r\n }\r\n\r\n e = getOriginalEvent(e);\r\n\r\n var xy = getXY(e);\r\n if (startXY && (Math.abs(xy[0] - startXY[0]) > options.distanceAllow || Math.abs(xy[1] - startXY[1]) > options.distanceAllow)) {\r\n removeActive(true);\r\n }\r\n });\r\n\r\n $(dom).bind(END_EVENT, function (e) {\r\n if (tapEl) {\r\n removeActive();\r\n }\r\n });\r\n\r\n // 手机来电等非用户取消操作时触发事件\r\n if (CANCEL_EVENT) {\r\n $(dom).bind(CANCEL_EVENT, function (e) {\r\n if (tapEl) {\r\n removeActive();\r\n }\r\n });\r\n }\r\n });\r\n\r\n // 更新默认值\r\n active.setOptions = function (opts) {\r\n options = this.options = $.extend({}, defaultOptions, opts);\r\n };\r\n ipu.active = active;\r\n})(ipu || window, jQuery);\r\n\r\n\n(function (ipu, $, iscroll) {\n\n /**\n * @deprecated 推荐使用 {@link HammerCarousel}\n * @uses IScroll.js\n * @class 简单封装IScroll.js的snap功能,实现banner功能\n *\n * @example\n * <!-- 组件html结构如下,li里内容可自定义 -->\n * <div class=\"ipu-carousel ipu-hammer-carousel\">\n * <ul class=\"ipu-carousel-wrapper\">\n * <li ><img src=\"../../biz/img/01.jpg\" alt=\"\"></li>\n * <li ><img src=\"../../biz/img/02.jpg\" alt=\"\"></li>\n * <li ><img src=\"../../biz/img/03.jpg\" alt=\"\"></li>\n * <li ><img src=\"../../biz/img/04.jpg\" alt=\"\"></li>\n * </ul>\n * </div>\n *\n * @constructor 不能直接访问该类,使用ipu.carousel(slt, option)生成实例 {@link ipu#carousel}\n * @param {Dom|JqueryObj|String} slt jquery对象或者jquery选择器或Dom元素\n * @param {Object} option 组件配置参数,默认配置见 {@link #cfg-defaultOption}\n */\n function Carousel(slt, option) {\n this.option = option = $.extend({}, this.defaultOption, option);\n this.el = $(slt).eq(0); // 一次只能实例化一个\n this.autoPlay = option.autoPlay;\n this.hasIndicator = option.indicator;\n this.callBack = option.callBack;\n this.currentIndex = null;\n\n this._init();\n this.play();\n }\n\n Carousel.prototype = {\n /**\n * 组件默认配置项\n *\n * @cfg {Object} defaultOption\n * @cfg {Number} defaultOption.index 默认显示的项\n * @cfg {Boolean} defaultOption.autoPlay 是否自动播放\n * @cfg {Number} defaultOption.duration 自动播放间隔,单位ms\n * @cfg {Boolean} defaultOption.indicator 是否生成指示器\n * @cfg {Function} defaultOption.callBack 切换显示时的回调函数\n * @cfg {Number} defaultOption.callBack.index 当前显示项索引\n *\n */\n defaultOption: {\n index: null, // 默认显示索引,未设置时先查找对就active,未找到时是0\n autoPlay: false, // 是否自动播放\n duration: 3000, // 自动播放延时\n indicator: false, // 是否生成指示器\n callBack: null // 变更时回调函数\n },\n _init: function () {\n var wrapper = $(\">.ipu-carousel-wrapper\", this.el);\n var carouselItems = $(\">li\", wrapper);\n this.carouselItems = carouselItems;\n this.size = carouselItems.size();\n var that = this;\n\n if (this.option.index == null) {\n var activeIndex = carouselItems.filter(\".ipu-current\").index();\n this.option.index = activeIndex != -1 ? activeIndex : 0;\n }\n\n if (this.hasIndicator) {\n this._addIndicator();\n }\n $(window).resize(function () {\n that.refresh();\n });\n var scrollOpt = {\n snap: \"li\", // carousel效果\n momentum: false, // 移除惯性处理\n scrollX: true, // X轴移动\n scrollY: false,\n hScrollbar: false, // 没有纵向滚动条\n onScrollStart: function () {\n that._pause();\n },\n onTouchEnd: function () {\n },\n onScrollEnd: function () {\n that._end();\n }\n };\n this.iscroll = new iscroll(this.el.get(0), scrollOpt);\n this.show(this.option.index, 0);\n },\n /**\n * 停止自动播放\n */\n stop: function () {\n this._pause();\n this.autoPlay = false;\n },\n _pause: function () {\n if (this.autoPlay && this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n },\n /**\n * 显示上一项\n */\n prev: function () {\n var index = this.currentIndex == 0 ? this.size - 1 : this.currentIndex - 1;\n this.show(index);\n },\n /**\n * 显示下一项\n */\n next: function () {\n var index = this.currentIndex == this.size - 1 ? 0 : this.currentIndex + 1;\n this.show(index);\n },\n /**\n * 显示索引index对应的索\n *\n * @param {Number} index 显示项索引\n */\n show: function (index, time) {\n this._pause();\n this.iscroll.scrollToPage(index, 0, time);\n },\n /**\n * 开始自动播放\n */\n play: function () {\n this.autoPlay = true;\n this._play();\n },\n /**\n * 若窗口发生大小变更,调用此方法更新位移\n */\n refresh: function () {\n this.show(this.currentIndex);\n },\n _play: function () {\n if (this.autoPlay && !this.timeoutId) {\n var that = this;\n this.timeoutId = setTimeout(function () {\n that.timeoutId = null;\n that.next();\n }, that.option.duration);\n }\n },\n _end: function () {\n var currentIndex = this.iscroll.currPageX;\n if (currentIndex != this.currentIndex) {\n if (this.callBack) {\n this.callBack(currentIndex, this.currentIndex);\n }\n this.currentIndex = currentIndex;\n\n if (this.hasIndicator) {\n this.indicatorIndexs.eq(currentIndex).addClass(\"ipu-current\").siblings().removeClass(\"ipu-current\");\n }\n this.carouselItems.eq(currentIndex).addClass(\"ipu-current\").siblings().removeClass(\"ipu-current\");\n }\n this._play();\n },\n _addIndicator: function () {\n var html = \"\";\n for (var i = 0; i < this.size; i++) {\n html += \"<li></li>\";\n }\n html = \"<ul class='ipu-carousel-indicator'>\" + html + \"</ul>\";\n this.indicator = $(html).appendTo(this.el);\n this.indicatorIndexs = $(\"li\", this.indicator);\n },\n destroy: function () {\n // 自己怎么销毁,相关事件移除??\n this.iscroll.destroy();\n }\n };\n\n /**\n * @member ipu\n * 生成Carousel实例,参数信息见{@link Carousel#method-constructor}\n *\n * @param {String} slt\n * @param {Object} option\n * @returns {Carousel}\n */\n ipu.carousel = function (slt, option) {\n return new Carousel(slt, option);\n };\n\n})(ipu || window, jQuery, iScroll);\n\n// todo:添加判断平台如mobile ,tablet, pc,参考其它类似功能库,添加webview判断\r\n;(function (ipu, $) {\r\n \"use strict\";\r\n var device = {}; // Classes\r\n var classNames = [];\r\n var ua = navigator.userAgent;\r\n\r\n var android = ua.match(/(Android);?[\\s\\/]+([\\d.]+)?/);\r\n var ipad = ua.match(/(iPad).*OS\\s([\\d_]+)/);\r\n var ipod = ua.match(/(iPod)(.*OS\\s([\\d_]+))?/);\r\n var iphone = !ipad && ua.match(/(iPhone\\sOS)\\s([\\d_]+)/);\r\n\r\n device.ios = device.android = device.iphone = device.ipad = device.androidChrome = false;\r\n\r\n\r\n // Android\r\n if (android) {\r\n device.os = 'android';\r\n device.osVersion = android[2];\r\n device.android = true;\r\n device.androidChrome = ua.toLowerCase().indexOf('chrome') >= 0;\r\n }\r\n if (ipad || iphone || ipod) {\r\n device.os = 'ios';\r\n device.ios = true;\r\n }\r\n // iOS\r\n if (iphone && !ipod) {\r\n device.osVersion = iphone[2].replace(/_/g, '.');\r\n device.iphone = true;\r\n }\r\n if (ipad) {\r\n device.osVersion = ipad[2].replace(/_/g, '.');\r\n device.ipad = true;\r\n }\r\n if (ipod) {\r\n device.osVersion = ipod[3] ? ipod[3].replace(/_/g, '.') : null;\r\n device.iphone = true;\r\n }\r\n // iOS 8+ changed UA\r\n if (device.ios && device.osVersion && ua.indexOf('Version/') >= 0) {\r\n if (device.osVersion.split('.')[0] === '10') {\r\n device.osVersion = ua.toLowerCase().split('version/')[1].split(' ')[0];\r\n }\r\n }\r\n\r\n // Pixel Ratio\r\n device.pixelRatio = window.devicePixelRatio || 1;\r\n classNames.push('pixel-ratio-' + Math.floor(device.pixelRatio));\r\n if (device.pixelRatio >= 2) {\r\n classNames.push('retina');\r\n }\r\n\r\n // OS classes\r\n if (device.os) {\r\n classNames.push(device.os, device.os + '-' + device.osVersion.split('.')[0], device.os + '-' + device.osVersion.replace(/\\./g, '-'));\r\n if (device.os === 'ios') {\r\n var major = parseInt(device.osVersion.split('.')[0], 10);\r\n for (var i = major - 1; i >= 6; i--) {\r\n classNames.push('ios-gt-' + i);\r\n }\r\n }\r\n }\r\n\r\n device.wx = /MicroMessenger/i.test(ua); // 是否微信\r\n device.ipu = /ipumobile/i.test(ua); // 是否ipu环境运行\r\n\r\n if (device.wx) {\r\n classNames.push('wx');\r\n }\r\n if (device.ipu) {\r\n classNames.push('ipu');\r\n }\r\n\r\n var classPrev = \"ipu-\";\r\n\r\n // Add html classes\r\n if (classNames.length > 0) {\r\n $('html').addClass(classPrev + classNames.join(' ' + classPrev));\r\n }\r\n\r\n ipu.device = device;\r\n})(ipu || window, jQuery);\r\n\n// dtPicker 此版本最大值与最小值,存在问题,当时间跨过一天时\r\n// show方法调用时,若没有值,则为当前值,还是有值就不变动了,点了确认按钮后,就不再变动了\r\n// 日期范围的选择处理\r\n// 不选择字符串连接符,合并后占空间\r\n\r\n(function (ipu, $) {\r\n var Picker = ipu.Picker;\r\n var defaultPickerDate = new Date(); // 有些时间不齐全。如time,需要一个默认日期来协助运算\r\n\r\n /**\r\n * @class 日期选择器,替代默认的web日历选择,日期格式如下<br>\r\n * type=datetime:yyyy-mm-dd hh:mi<br>\r\n * type=date:yyyy-mm-dd<br>\r\n * type=time: hh:mi<br>\r\n * type=month: yyyy-mm<br>\r\n * type=hour: yyyy-mm-dd hh<br>\r\n *\r\n * @constructor 不能直接访问该,调用{@link ipu#dtPicker}生成实例\r\n * @param {object} option 组件参数,默认配置见 {@link #cfg-defaultOption}\r\n */\r\n function DtPicker(option) {\r\n this.option = $.extend({}, this.defaultOption, option);\r\n\r\n if (!Picker) {\r\n Picker = ipu.Picker;\r\n }\r\n this._init();\r\n }\r\n\r\n /**\r\n * 组件默认配置项\r\n *\r\n * @cfg {Object} defaultOption=\r\n * @cfg {String} defaultOption.template 组件模板html,不建议变更\r\n * @cfg {[String]} defaultOption.buttons=['取消', '确认', '清除'] 按钮名称\r\n * @cfg {[String]} defaultOption.labels=['年', '月', '日', '时', '分'] 年月日标签\r\n * @cfg {datetime|time|date|hour|month} defaultOption.type='datetime' 日期类型\r\n * @cfg {Boolean} defaultOption.hasClear=false 是否显示清除按钮\r\n * @cfg {Date} defaultOption.beginDate=null 日期开始时间,默认设置为当时间前5年\r\n * @cfg {Date} defaultOption.endDate=null 日期结束时间,默认设置为开始时间后10年\r\n * @cfg {Function} defaultOption.callBack=null 点击按钮时的回调函数,回调的参数同{@link #show show()}法设置 的回调\r\n */\r\n DtPicker.prototype.defaultOption = {\r\n template: '<div class=\"ipu-poppicker ipu-dtpicker\">'\r\n + '<div class=\"ipu-poppicker-header\">'\r\n + '<button class=\"ipu-btn ipu-btn-s ipu-poppicker-btn-cancel\">取消</button>'\r\n + '<button class=\"ipu-btn ipu-btn-s ipu-poppicker-btn-ok\">确定</button>'\r\n + '<button class=\"ipu-btn ipu-btn-s ipu-poppicker-btn-clear\">清除</button>'\r\n + '</div>'\r\n + '<div class=\"ipu-poppicker-title\">'\r\n + '<label class=\"ipu-dtpicker-y\"></label>'\r\n + '<label class=\"ipu-dtpicker-m\"></label>'\r\n + '<label class=\"ipu-dtpicker-d\"></label>'\r\n + '<label class=\"ipu-dtpicker-h\"></label>'\r\n + '<label class=\"ipu-dtpicker-mi\"></label>'\r\n + '</div>'\r\n + '<div>'\r\n + '<div class=\"ipu-poppicker-body\">'\r\n + '<div class=\"ipu-picker\" data-id=\"picker-y\">'\r\n + '<div class=\"ipu-picker-selectbox\"></div>'\r\n + '<ul></ul>'\r\n + '</div>'\r\n + '<div class=\"ipu-picker\" data-id=\"picker-m\">'\r\n + '<div class=\"ipu-picker-selectbox\"></div>'\r\n + '<ul></ul>'\r\n + '</div>'\r\n + '<div class=\"ipu-picker\" data-id=\"picker-d\">'\r\n + '<div class=\"ipu-picker-selectbox\"></div>'\r\n + '<ul></ul>'\r\n + '</div>'\r\n + '<div class=\"ipu-picker\" data-id=\"picker-h\">'\r\n + '<div class=\"ipu-picker-selectbox\"></div>'\r\n + '<ul></ul>'\r\n + '</div>'\r\n + '<div class=\"ipu-picker\" data-id=\"picker-mi\">'\r\n + '<div class=\"ipu-picker-selectbox\"></div>'\r\n + '<ul></ul>'\r\n + '</div>'\r\n + '</div>'\r\n + '</div>',\r\n buttons: ['取消', '确认', '清除'],\r\n labels: ['年', '月', '日', '时', '分'],\r\n type: 'datetime',\r\n customData: {},\r\n hasClear: false,\r\n beginDate: null,\r\n endDate: null,\r\n callBack: null\r\n };\r\n\r\n DtPicker.prototype._init = function () {\r\n var self = this;\r\n this.mask = this.createMask();\r\n\r\n var _picker = this.holder = $(this.option.template).appendTo(\"body\");\r\n var ui = self.ui = {\r\n picker: this.holder,\r\n ok: $('.ipu-poppicker-btn-ok', _picker),\r\n cancel: $('.ipu-poppicker-btn-cancel', _picker),\r\n clear: $('.ipu-poppicker-btn-clear', _picker),\r\n buttons: $('.ipu-poppicker-header .ipu-btn', _picker),\r\n labels: $('.ipu-poppicker-title label', _picker)\r\n };\r\n\r\n\r\n ui.i = new Picker($('[data-id=\"picker-mi\"]', _picker), {listen: false}); // 分钟变更无需要处理\r\n\r\n ui.h = new Picker($('[data-id=\"picker-h\"]', _picker), { // 小时变更,有最小值或最大值,需要变更分钟\r\n listen: false,\r\n onChange: function (item, index) {\r\n if (index !== null && (self.option.beginMonth || self.option.endMonth)) {\r\n self._createMinutes();\r\n }\r\n }\r\n });\r\n\r\n ui.d = new Picker($('[data-id=\"picker-d\"]', _picker), { //仅提供了beginDate时,触发day,hours,minutes的change\r\n listen: false,\r\n onChange: function (item, index) {\r\n if (index !== null && (self.option.beginMonth || self.option.endMonth)) {\r\n self._createHours();\r\n }\r\n }\r\n });\r\n\r\n ui.m = new Picker($('[data-id=\"picker-m\"]', _picker), { // 月变更时,总要变更day\r\n listen: false,\r\n onChange: function (item, index) {\r\n if (index !== null) {\r\n self._createDay();\r\n }\r\n }\r\n });\r\n\r\n ui.y = new Picker($('[data-id=\"picker-y\"]', _picker), { // 年发生变更,如果没有结束月,此时有所有的月,是不需要变更月的,只需要变更day\r\n listen: false,\r\n onChange: function (item, index) {\r\n if (index != null) {\r\n if (self.option.beginMonth || self.option.endMonth) {\r\n self._createMonth();\r\n } else {\r\n self._createDay();\r\n }\r\n }\r\n }\r\n });\r\n\r\n\r\n self._create();\r\n\r\n //设定label\r\n self._setLabels();\r\n self._setButtons();\r\n //设定类型\r\n ui.picker.attr('data-type', this.option.type);\r\n\r\n //设定默认值\r\n\r\n self._setSelectedValue(this.option.value);\r\n\r\n //防止滚动穿透 TODO:待确认情况\r\n /* self.ui.picker.addEventListener($.EVENT_START, function (event) {\r\n event.preventDefault();\r\n }, false);\r\n self.ui.picker.addEventListener($.EVENT_MOVE, function (event) {\r\n event.preventDefault();\r\n }, false);*/\r\n };\r\n\r\n /**\r\n * 返回当前选中的日期,只有在点确认时,返回的才是正确的值,在点清除、或取消后,调用此方法返回的值不可控\r\n *\r\n * @return 选择的日期信息\r\n * @return {datetime|time|date|hour|month} return.type 日期类型\r\n * @return {String} return.text 日期文本(text字段)拼接,格式yyyy-mm-dd hh:mi 根据上面的日期类型返回对应字符串\r\n * @return {String} return.value 日期项值(value字段)拼接\r\n * @return {Object} return.y 选择的年项\r\n * @return {Object} return.m 选择的月项\r\n * @return {Object} return.d 选择的日项\r\n * @return {Object} return.h 选择的时项\r\n * @return {Object} return.i 选择的分项\r\n * @return {Function} return.toString 返回value字段的值\r\n */\r\n DtPicker.prototype.getSelected = function () {\r\n var self = this;\r\n var ui = self.ui;\r\n var type = self.option.type;\r\n var selected = {\r\n type: type,\r\n y: ui.y.getSelectedItem(),\r\n m: ui.m.getSelectedItem(),\r\n d: ui.d.getSelectedItem(),\r\n h: ui.h.getSelectedItem(),\r\n i: ui.i.getSelectedItem(),\r\n toString: function () {\r\n return this.value;\r\n }\r\n };\r\n switch (type) {\r\n case 'datetime':\r\n selected.value = selected.y.value + '-' + selected.m.value + '-' + selected.d.value + ' ' + selected.h.value + ':' + selected.i.value;\r\n selected.text = selected.y.text + '-' + selected.m.text + '-' + selected.d.text + ' ' + selected.h.text + ':' + selected.i.text;\r\n break;\r\n case 'date':\r\n selected.value = selected.y.value + '-' + selected.m.value + '-' + selected.d.value;\r\n selected.text = selected.y.text + '-' + selected.m.text + '-' + selected.d.text;\r\n break;\r\n case 'time':\r\n selected.value = selected.h.value + ':' + selected.i.value;\r\n selected.text = selected.h.text + ':' + selected.i.text;\r\n break;\r\n case 'month':\r\n selected.value = selected.y.value + '-' + selected.m.value;\r\n selected.text = selected.y.text + '-' + selected.m.text;\r\n break;\r\n case 'hour':\r\n selected.value = selected.y.value + '-' + selected.m.value + '-' + selected.d.value + ' ' + selected.h.value;\r\n selected.text = selected.y.text + '-' + selected.m.text + '-' + selected.d.text + ' ' + selected.h.text;\r\n break;\r\n }\r\n return selected;\r\n };\r\n\r\n DtPicker.prototype._setSelectedValue = function (value) {\r\n var self = this;\r\n var ui = self.ui;\r\n\r\n if (!value) {\r\n if (this.option.type == 'time') {\r\n value = '00:00';\r\n } else {\r\n value = defaultPickerDate.getFullYear() + '-' + (defaultPickerDate.getMonth() + 1) + '-' + defaultPickerDate.getDate() + ' '\r\n + defaultPickerDate.getHours() + ':' + defaultPickerDate.getMinutes();\r\n }\r\n }\r\n var parsedValue = self._parseSetValue(value);\r\n\r\n ui.y.setListen(true);\r\n ui.m.setListen(false);\r\n ui.d.setListen(false);\r\n ui.h.setListen(false);\r\n ui.i.setListen(false);\r\n ui.y.setSelectedValue(parsedValue.y);\r\n\r\n ui.m.setListen(true);\r\n ui.m.setSelectedValue(parsedValue.m);\r\n\r\n ui.d.setListen(true);\r\n ui.d.setSelectedValue(parsedValue.d);\r\n\r\n ui.h.setListen(true);\r\n ui.h.setSelectedValue(parsedValue.h);\r\n\r\n ui.i.setListen(true);\r\n ui.i.setSelectedValue(parsedValue.i);\r\n\r\n this.value = this.getSelected().value;\r\n };\r\n\r\n /**\r\n * 设置日期值,value为字符串时,格式请参照 yyyy-mm-dd hh:mi具体格式与配置项type相关\r\n *\r\n * @param {String|Date} value\r\n */\r\n DtPicker.prototype.setSelectedValue = function (value) {\r\n this._setSelectedValue(value);\r\n };\r\n\r\n /**\r\n * 是否润年\r\n *\r\n * @param {Number} year 年份\r\n * @returns {Boolean}\r\n */\r\n DtPicker.prototype.isLeapYear = function (year) {\r\n return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);\r\n };\r\n\r\n DtPicker.prototype._inArray = function (array, item) {\r\n for (var index in array) {\r\n var _item = array[index];\r\n if (_item === item) return true;\r\n }\r\n return false;\r\n };\r\n\r\n DtPicker.prototype.getDayNum = function (year, month) {\r\n var self = this;\r\n if (self._inArray([1, 3, 5, 7, 8, 10, 12], month)) {\r\n return 31;\r\n } else if (self._inArray([4, 6, 9, 11], month)) {\r\n return 30;\r\n } else if (self.isLeapYear(year)) {\r\n return 29;\r\n } else {\r\n return 28;\r\n }\r\n };\r\n\r\n DtPicker.prototype._fill = function (num) {\r\n num = num.toString();\r\n if (num.length < 2) {\r\n num = 0 + num;\r\n }\r\n return num;\r\n };\r\n\r\n DtPicker.prototype._isBeginYear = function () {\r\n return this.option.beginYear === parseInt(this.ui.y.getSelectedValue());\r\n };\r\n\r\n DtPicker.prototype._isBeginMonth = function () {\r\n return this.option.beginMonth && this._isBeginYear() && this.option.beginMonth === parseInt(this.ui.m.getSelectedValue());\r\n };\r\n\r\n DtPicker.prototype._isBeginDay = function () {\r\n return this._isBeginMonth() && this.option.beginDay === parseInt(this.ui.d.getSelectedValue());\r\n };\r\n\r\n DtPicker.prototype._isBeginHours = function () {\r\n return this._isBeginDay() && this.option.beginHours === parseInt(this.ui.h.getSelectedValue());\r\n };\r\n\r\n DtPicker.prototype._isEndYear = function () {\r\n return this.option.endYear === parseInt(this.ui.y.getSelectedValue());\r\n };\r\n\r\n DtPicker.prototype._isEndMonth = function () {\r\n return this.option.endMonth && this._isEndYear() && this.option.endMonth === parseInt(this.ui.m.getSelectedValue());\r\n };\r\n\r\n DtPicker.prototype._isEndDay = function () {\r\n return this._isEndMonth() && this.option.endDay === parseInt(this.ui.d.getSelectedValue());\r\n };\r\n\r\n DtPicker.prototype._isEndHours = function () {\r\n return this._isEndDay() && this.option.endHours === parseInt(this.ui.h.getSelectedValue());\r\n };\r\n\r\n DtPicker.prototype._createYear = function () {\r\n var self = this;\r\n var option = self.option;\r\n var ui = self.ui;\r\n\r\n //生成年列表\r\n var yArray = [];\r\n if (option.customData.y) {\r\n yArray = option.customData.y;\r\n } else {\r\n var yBegin = option.beginYear;\r\n var yEnd = option.endYear;\r\n for (var y = yBegin; y <= yEnd; y++) {\r\n yArray.push({\r\n text: y + '',\r\n value: y\r\n });\r\n }\r\n }\r\n ui.y.setItems(yArray);\r\n };\r\n\r\n DtPicker.prototype._createMonth = function () {\r\n var self = this;\r\n var option = self.option;\r\n var ui = self.ui;\r\n\r\n //生成月列表\r\n var mArray = [];\r\n if (option.customData.m) {\r\n mArray = option.customData.m;\r\n } else {\r\n var m = option.beginMonth && self._isBeginYear() ? option.beginMonth : 1;\r\n var maxMonth = option.endMonth && self._isEndYear() ? option.endMonth : 12;\r\n for (; m <= maxMonth; m++) {\r\n var val = self._fill(m);\r\n mArray.push({\r\n text: val,\r\n value: m\r\n });\r\n }\r\n }\r\n ui.m.setItems(mArray);\r\n };\r\n\r\n DtPicker.prototype._createDay = function () {\r\n var self = this;\r\n var option = self.option;\r\n var ui = self.ui;\r\n\r\n //生成日列表\r\n var dArray = [];\r\n if (option.customData.d) {\r\n dArray = option.customData.d;\r\n } else {\r\n var d = self._isBeginMonth() ? option.beginDay : 1;\r\n var maxDay = self._isEndMonth() ? option.endDay : self.getDayNum(parseInt(this.ui.y.getSelectedValue()), parseInt(this.ui.m.getSelectedValue()));\r\n for (; d <= maxDay; d++) {\r\n var val = self._fill(d);\r\n dArray.push({\r\n text: val,\r\n value: d\r\n });\r\n }\r\n }\r\n ui.d.setItems(dArray);\r\n //current = current || ui.d.getSelectedValue();\r\n //ui.d.setSelectedValue(current);\r\n };\r\n\r\n DtPicker.prototype._createHours = function () {\r\n var self = this;\r\n var option = self.option;\r\n var ui = self.ui;\r\n //生成时列表\r\n var hArray = [];\r\n if (option.customData.h) {\r\n hArray = option.customData.h;\r\n } else {\r\n var h = self._isBeginDay() ? option.beginHours : 0;\r\n var maxHours = self._isEndDay() ? option.endHours : 23;\r\n for (; h <= maxHours; h++) {\r\n var val = self._fill(h);\r\n hArray.push({\r\n text: val,\r\n value: h\r\n });\r\n }\r\n }\r\n ui.h.setItems(hArray);\r\n //ui.h.setSelectedValue(current);\r\n };\r\n\r\n DtPicker.prototype._createMinutes = function () {\r\n var self = this;\r\n var option = self.option;\r\n var ui = self.ui;\r\n\r\n //生成分列表\r\n var iArray = [];\r\n if (option.customData.i) {\r\n iArray = option.customData.i;\r\n } else {\r\n var i = self._isBeginHours() ? option.beginMinutes : 0;\r\n var maxMinutes = self._isEndHours() ? option.endMinutes : 59;\r\n for (; i <= maxMinutes; i++) {\r\n var val = self._fill(i);\r\n iArray.push({\r\n text: val,\r\n value: i\r\n });\r\n }\r\n }\r\n ui.i.setItems(iArray);\r\n //ui.i.setSelectedValue(current);\r\n };\r\n\r\n DtPicker.prototype._setLabels = function () {\r\n var self = this;\r\n var option = self.option;\r\n var ui = self.ui;\r\n ui.labels.each(function (i, label) {\r\n label.innerText = option.labels[i];\r\n });\r\n };\r\n\r\n DtPicker.prototype._setButtons = function () {\r\n var self = this;\r\n var option = self.option;\r\n var ui = self.ui;\r\n ui.cancel.text(option.buttons[0]);\r\n ui.ok.text(option.buttons[1]);\r\n\r\n if (option.hasClear) {\r\n ui.clear.text(option.buttons[2])\r\n } else {\r\n ui.clear.hide();\r\n }\r\n\r\n ui.buttons.each(function (index) {\r\n $(this).click(function () {\r\n self.clickCall(index);\r\n })\r\n })\r\n };\r\n\r\n // 解析设置的值,目前是字符串,完整日期格式 2012-12-12 12:21\r\n // 对于time类型时,或未完整的时间值,使用defaultPickerDate来填充\r\n DtPicker.prototype._parseSetValue = function (value) {\r\n var now = defaultPickerDate;\r\n var type = this.option.type;\r\n\r\n var rs = {\r\n y: now.getFullYear(),\r\n m: now.getMonth() + 1,\r\n d: now.getDate(),\r\n h: now.getHours(),\r\n i: now.getMinutes()\r\n };\r\n\r\n if (value instanceof Date) {\r\n if (type == 'time') {\r\n value = value.getHours() + \":\" + value.getMinutes();\r\n } else {\r\n value = value.getFullYear() + '-' + (value.getMonth() + 1) + '-' + value.getDate() + ' '\r\n + value.getHours() + \":\" + value.getMinutes();\r\n }\r\n }\r\n\r\n var parts = value.replace(\":\", \"-\").replace(\" \", \"-\").split(\"-\");\r\n for (var i = 0, j = parts.length; i < j; i++) {\r\n parts[i] = parseInt(parts[i]);\r\n }\r\n\r\n if (type == 'datetime') {\r\n rs.y = parts[0];\r\n rs.m = parts[1];\r\n rs.d = parts[2]; //\r\n rs.h = parts[3]; //\r\n rs.i = parts[4];\r\n } else if (type == 'date') {\r\n rs.y = parts[0];\r\n rs.m = parts[1];\r\n rs.d = parts[2]; //\r\n rs.h = 0; //\r\n rs.i = 0;\r\n } else if (type == 'time') {\r\n rs.h = parts[0]; //\r\n rs.i = parts[1];\r\n } else if (type == 'hour') {\r\n rs.y = parts[0];\r\n rs.m = parts[1];\r\n rs.d = parts[2]; //\r\n rs.h = parts[3]; //\r\n rs.i = 0;\r\n } else if (type == 'month') {\r\n rs.y = parts[0];\r\n rs.m = parts[1];\r\n rs.d = 1; //\r\n rs.h = 0; //\r\n rs.i = 0;\r\n }\r\n\r\n return rs;\r\n };\r\n\r\n // 生成日期数据\r\n DtPicker.prototype._create = function () {\r\n var self = this;\r\n var option = this.option;\r\n var now = defaultPickerDate;\r\n var beginDate = option.beginDate;\r\n\r\n if (beginDate) { // 若有设置开始日期\r\n beginDate = this._parseSetValue(beginDate);\r\n option.beginYear = beginDate.y;\r\n option.beginMonth = beginDate.m;\r\n option.beginDay = beginDate.d;\r\n option.beginHours = beginDate.h;\r\n option.beginMinutes = beginDate.i;\r\n } else if (option.type == 'time') { // 未设置开始日期,但日期格式是time\r\n option.beginYear = now.getFullYear();\r\n option.beginMonth = now.getMonth() + 1;\r\n option.beginDay = now.getDate();\r\n option.beginHours = 0;\r\n option.beginMinutes = 0;\r\n } else {\r\n option.beginYear = now.getFullYear() - 5; // 其它,未设置开始日期,type也不为time,设置默认起始时间\r\n }\r\n\r\n var endDate = option.endDate;\r\n if (endDate) { //设定了结束日期\r\n endDate = this._parseSetValue(endDate);\r\n option.endYear = endDate.y;\r\n option.endMonth = endDate.m;\r\n option.endDay = endDate.d;\r\n option.endHours = endDate.h;\r\n option.endMinutes = endDate.i;\r\n } else if (option.type == 'time') {\r\n option.endYear = now.getFullYear();\r\n option.endMonth = now.getMonth() + 1;\r\n option.endDay = now.getDate();\r\n option.endHours = 23;\r\n option.endMinutes = 59;\r\n } else {\r\n option.endYear = option.beginYear + 10;\r\n }\r\n\r\n //生成\r\n self._createYear();\r\n self._createMonth();\r\n self._createDay();\r\n self._createHours();\r\n self._createMinutes();\r\n };\r\n\r\n /**\r\n * 设置组件日期范围\r\n *\r\n * @param {String|Date} beginDate 开始时间\r\n * @param {Stirng|Date} endDate 结束时间\r\n */\r\n DtPicker.prototype.setDateRange = function (beginDate, endDate) {\r\n this.option.beginDate = beginDate;\r\n this.option.endDate = endDate;\r\n this._create();\r\n };\r\n\r\n /**\r\n * 设置开始组件的开始据时间\r\n * @param {String|Date} date\r\n */\r\n DtPicker.prototype.setBeginDate = function (date) {\r\n this.option.beginDate = date;\r\n this._create();\r\n };\r\n\r\n /**\r\n * 设置组件的结束时间\r\n *\r\n * @param {String|Date} date\r\n */\r\n DtPicker.prototype.setEndDate = function (date) {\r\n this.option.endDate = date;\r\n this._create();\r\n };\r\n\r\n DtPicker.prototype.dispose = function () {\r\n var self = this;\r\n self.hide();\r\n setTimeout(function () {\r\n self.ui.picker.parentNode.removeChild(self.ui.picker);\r\n for (var name in self) {\r\n self[name] = null;\r\n delete self[name];\r\n }\r\n self.disposed = true;\r\n }, 300);\r\n };\r\n\r\n /**\r\n * 显示组件\r\n *\r\n * @param {Function} callBack 点击按钮时的回调函数,设置此参数会覆盖初始化时的回调函数\r\n * @param {Object} callBack.sltDate 当前选中的日期信息,具体格式,见方法{@link #getSelected getSelected()}的返回\r\n * @param {Number} callBack.index 被点击的按钮索引,0取消,1确认,2清除\r\n */\r\n DtPicker.prototype.show = function (callBack) {\r\n if (callBack) {\r\n this.option.callBack = callBack;\r\n }\r\n this.mask.show();\r\n this.setSelectedValue(this.value);\r\n this.holder.addClass(\"ipu-current\");\r\n };\r\n\r\n DtPicker.prototype.clickCall = function (index) {\r\n var self = this;\r\n var sltDate = self.getSelected();\r\n var rs = self.option.callBack.call(this, sltDate, index);\r\n if (rs !== false) {\r\n if (index == 1) { // 假定确认按钮在第二个位置,传回true则存储当前值\r\n self.value = sltDate.value;\r\n } else if (index == 2) {\r\n self.value = null;\r\n }\r\n self.hide();\r\n }\r\n };\r\n\r\n /**\r\n * 隐藏组件\r\n */\r\n DtPicker.prototype.hide = function () {\r\n this.mask.close();\r\n this.holder.removeClass(\"ipu-current\");\r\n };\r\n\r\n // 应该移除callback参数,提取出业成一个工具方法\r\n DtPicker.prototype.createMask = function (callback) {\r\n var self = this;\r\n var element = document.createElement('div');\r\n element.classList.add(\"ipu-picker-backup\");\r\n //element.addEventListener($.EVENT_MOVE, $.preventDefault);\r\n element.addEventListener('click', function () {\r\n self.clickCall(0);\r\n });\r\n var mask = [element];\r\n mask._show = false;\r\n mask.show = function () {\r\n mask._show = true;\r\n element.setAttribute('style', 'opacity:1');\r\n document.body.appendChild(element);\r\n return mask;\r\n };\r\n mask._remove = function () {\r\n if (mask._show) {\r\n mask._show = false;\r\n element.setAttribute('style', 'opacity:0');\r\n setTimeout(function () {\r\n var body = document.body;\r\n element.parentNode === body && body.removeChild(element);\r\n }, 350);\r\n }\r\n return mask;\r\n };\r\n mask.close = function () {\r\n if (mask._show) {\r\n if (callback) {\r\n if (callback() !== false) {\r\n mask._remove();\r\n }\r\n } else {\r\n mask._remove();\r\n }\r\n }\r\n };\r\n return mask;\r\n };\r\n\r\n /**\r\n * @member ipu\r\n * 生成DtPicker实例,参数信息见{@link DtPicker#method-constructor}\r\n *\r\n * @param {Object} option\r\n * @returns {DtPicker}\r\n */\r\n ipu.dtPicker = function (option) {\r\n return new DtPicker(option);\r\n };\r\n})(ipu || window, jQuery);\r\n\n// 更新方法和属性命名\n// 不能支持元素隐藏时,使用百比分处理移动距离。。。?\n// 支持两个以内容同时显示\n// 支持类似snap实现\n// 上下移动?\n// 理想是移除carousel.js的实现,用hammerCarousel.js实现所有相关功能\n// indicatorPosition: 'center', // left|right|center;暂不支持,不知道怎么支持在中间显示,用全宽度,配合point-event:none,可能ok,参考humUI和mui\n\n(function (ipu, $, Hammer) {\n /**\n * @class\n * @uses Hammer.js\n * 通过hammer.js实现的banner功能组件,\n * 因为实现轮播,显示第一项后,再显示第一项,所以第一项有被复制到添加到最后\n *\n * @example\n * <!-- 组件html结构如下,li里的内容用户可自定义 -->\n * <div class=\"ipu-carousel ipu-hammer-carousel\">\n * <ul class=\"ipu-carousel-wrapper\">\n * <li ><img src=\"../../biz/img/01.jpg\" alt=\"\"></li>\n * <li ><img src=\"../../biz/img/02.jpg\" alt=\"\"></li>\n * <li ><img src=\"../../biz/img/03.jpg\" alt=\"\"></li>\n * <li ><img src=\"../../biz/img/04.jpg\" alt=\"\"></li>\n * </ul>\n * </div>\n *\n * @constructor 不能直接访问该类,调用 {@link ipu#hammerCarousel}生成实例\n * @param {String|JqueryObj} slt\n * jquery选择器字符串或jquery对象,用来查找要被组件初始化化的dom\n * @param {Object} option 组件配置参数,默认配置见 {@link #cfg-defaultOption}\n */\n function HammerCarousel(slt, option) {\n this.option = $.extend({}, this.defaultOption, option);\n this.el = $(slt).get(0);\n this._init();\n }\n\n $.extend(HammerCarousel.prototype, {\n /**\n * 组件默认配置项\n *\n * @cfg {Object} defaultOption\n * @cfg {Number} defaultOption.index 初始化时显示第几项,用户未指定时,会查找子项内容上有ipu-current的项显示,默认显示第一项\n * @cfg {Boolean} defaultOption.loop 是否循环切换,只有轮播切换时,才能自动轮播\n * @cfg {Boolean} defaultOption.autoPlay 是否自动轮播\n * @cfg {Number} defaultOption.duration 自动轮播时的间隔时间,单位ms\n * @cfg {Boolean} defaultOption.indicator 是否生成banner提示器,true右下角出现小点\n * @cfg {Function} defaultOption.callBack 轮播显示某项时的回调函数\n * @cfg {Number} defaultOption.callBack.index 当前显示的项索引\n * @cfg {Function} defaultOption.clickBack\n * 切换项时被点击时的回调函数,此处主要是为了处理复制项与第一项的点击事件进行处理,\n * 让用户不关注点击的是第一项或是复制项,回调作用域为组件对象\n * @cfg {Number} defaultOption.clickBack.index 点击的项索引\n */\n defaultOption: {\n index: null,\n loop: false,\n autoPlay: false,\n duration: 3000,\n indicator: false,\n callBack: null,\n clickBack: null\n },\n _init: function () {\n this.wrapper = $(\">.ipu-carousel-wrapper\", this.el);\n this.carouselItems = $(\">li\", this.wrapper);\n this.itemSize = this.carouselItems.size(); // 子项数量\n\n this.showItemSize = 1; // 假设一屏默认显示1个,所以做循环显示只需要复制一个子项\n this.carouselItemWides = []; // 子项宽度尺寸\n \n /** @property {Number} 当前显示子项索引,从0开始 */\n this.currentIndex = 0; // 当前显示子项索引\n this.moveLen = 0; // 当前滚动移动距离\n\n /** @type {Boolean} 循环展示时,第一项会被复制,显示项是第一项时,是否为第一项的复制项 */\n this.cloneItem = false; // index是0的时候,有可能显示的是第一项,也有可能显示的是复制项,这个参数用来标记是否复制项\n\n if (this.option.indicator) {\n this._addIndicator();\n }\n\n // 如果做循环展示,则要复制起始展示项到最后面\n if (this.option.loop) {\n this.carouselItems.slice(0, this.showItemSize).clone().appendTo(this.wrapper); // 这里假设每个元素宽度都是相等的\n }\n\n var that = this;\n if (this.option.clickBack) {\n $(\">li\", this.wrapper).each(function (i) {\n $(this).click(function () {\n that.option.clickBack.call(this, i % that.size);\n });\n })\n }\n\n this.hammer = new Hammer.Manager(this.el);\n this.hammer.add(new Hammer.Pan({direction: Hammer.DIRECTION_HORIZONTAL, threshold: 10}));\n this.hammer.on(\"panstart panmove panend pancancel\", Hammer.bindFn(this._onPan, this));\n\n this._sizeCount();\n $(window).resize(function () { // 在窗口尺寸变化时,更新尺寸信息\n that.refresh();\n });\n\n if (this.option.index == null) {\n var activeIndex = this.carouselItems.filter(\".ipu-current\").index();\n this.currentIndex = activeIndex != -1 ? activeIndex : 0;\n }\n\n this.show(this.currentIndex, false);\n },\n /**\n * 停止自动滚动\n */\n stop: function () {\n this._pause();\n this.option.autoPlay = false;\n },\n _pause: function () {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n },\n /**\n * 切换到上一项\n */\n prev: function () {\n var index;\n if(this.option.loop){\n index = this.currentIndex == 0 ? this.itemSize - 1 : this.currentIndex - 1;\n if (index == this.itemSize - 1) {\n this._show(this.itemSize, false);\n this.wrapper.width();\n }\n }else{\n index = (this.currentIndex - 1 + this.itemSize) % this.itemSize;\n }\n\n this._show(index);\n },\n /**\n * 切换到下一项\n */\n next: function () {//下一张\n var index\n if(this.option.loop){\n index = this.currentIndex == this.itemSize ? 1 : this.currentIndex + 1;\n if (index == 1) {\n this._show(0, false);\n this.wrapper.width();\n }\n } else {\n index = (this.currentIndex + 1) % this.itemSize;\n }\n\n this._show(index);\n },\n /**\n * 切换显示指定项\n *\n * @param {Number} index 要切换到的项索引\n *\n */\n show: function (index) {//跳到指定索引处\n var index = index % this.itemSize;\n if (index < 0) {\n index = this.itemSize + index;\n }\n this._show(index); // 默认追加动画\n },\n /**\n * 自动轮播\n */\n play: function () {\n this.option.autoPlay = true;\n this._play();\n },\n _play: function () {\n if (this.option.autoPlay && this.option.loop && !this.timeoutId) {\n var that = this;\n this.timeoutId = setTimeout(function () {\n that.timeoutId = null;//清空这个timeoutId,代表该次处理已经执行了\n that.next();\n }, that.option.duration);\n }\n },\n _addIndicator: function () {\n var html = \"\";\n for (var i = 0; i < this.itemSize; i++) {\n html += \"<li></li>\";\n }\n html = \"<ul class='ipu-carousel-indicator'>\" + html + \"</ul>\";\n this.indicator = $(html).appendTo(this.el);\n this.indicatorIndexs = $(\"li\", this.indicator);\n },\n _sizeCount: function () {\n this.wrapperWidth = this.wrapper.outerWidth(true);\n this.itemWidth = this.carouselItems.eq(0).outerWidth(true);\n this.mostSize = this.itemSize * this.itemWidth; // 宽度*数量\n $(this.wrapper).removeClass(\"ipu-carousel-animate\").width();\n this.carouselItemWides = [];\n\n var that = this;\n $(\">li\", this.wrapper).each(function (index, dom) { // 此处要注意,最后一个子项是后加进入的,要重新使用jquery处理一下,不能直接使用this.xx来处理\n that.carouselItemWides[index] = $(this).position().left;\n });\n },\n /**\n * 宽度信息或尺寸信息发生变更时,进行刷新计算\n * 判断是否需要重新计算尺寸,若宽度尺寸发生变化,进行重新尺寸计算\n */\n refresh: function () {\n if (this.wrapperWidth != this.wrapper.outerWidth(true)) {\n this._sizeCount();\n this._show(this.currentIndex, false); //新的位置\n }\n },\n _move: function (moveLen) { // 拖动时的处理\n this._pause();\n $(this.wrapper).removeClass(\"ipu-carousel-animate\");\n\n if(this.option.loop){\n var move = (this.moveLen - moveLen) % this.mostSize;\n move = (move + this.mostSize) % this.mostSize;\n\n }else{\n var move = this.moveLen - moveLen;\n if (move < 0) {\n move = move / 2;\n }else if(move > this.mostSize){\n move = this.mostSize + (move - this.mostSize)/2;\n }\n }\n\n this.displayMoveLen = move;\n move = -move + \"px\";\n $(this.wrapper).css(\"transform\", \"translate3d(\" + move + \", 0, 0)\");\n },\n _show: function (index, animate) { // 知道最终移动到的项时,调用\n if (animate !== false) { // 默认值为true\n animate = true;\n }\n\n this._pause();\n $(this.wrapper).toggleClass(\"ipu-carousel-animate\", animate);\n this.currentIndex = index % this.itemSize;\n this.cloneItem = index == this.itemSize;\n\n this.moveLen = this.carouselItemWides[index];\n var move = -this.moveLen + \"px\";\n\n $(this.wrapper).css(\"transform\", \"translate3d(\" + move + \", 0, 0)\");\n\n var currentIndex = this.currentIndex;\n if (animate && this.option.callBack) {\n this.option.callBack(currentIndex, this.cloneItem);//返回当前索引,以及是滞最后一项参数\n }\n\n if (this.indicator) {\n this.indicatorIndexs.eq(currentIndex).addClass(\"ipu-current\").siblings().removeClass(\"ipu-current\");\n }\n\n this._play();//处理自动播放\n },\n _onPan: function (ev) {\n var delta = ev.deltaX; // 内容往左,deltaX为正值\n\n // pancancel与panend,有效的pan事件结束与无效的pan事件结束?\n if (ev.type == 'panend' || ev.type == 'pancancel'){\n var value = delta / this.itemWidth;\n var intValue = parseInt(Math.abs(value)); // 取整数\n var decimal = Math.abs(value) % 1; // 取小数\n\n if (decimal > 0.2) { // 滑动超过页面宽20%;\n intValue = intValue + 1;\n }\n if (delta > 0) {\n intValue = -intValue;\n }\n var index;\n\n if(this.option.loop) {\n index = (this.currentIndex + intValue) % this.itemSize;\n index = (index + this.itemSize) % this.itemSize; // 因为可能是个负值,转换成正值\n\n // 当前位移大于一个项的长度,这由move方法导致的,所以此时只能是最后一项在显示,所以要显示最后一项\n if (index == 0 && this.displayMoveLen > this.itemWidth) {\n index = this.itemSize;\n }\n } else { // 非循环时\n index = this.currentIndex + intValue;\n if (index < 0) {\n index = 0;\n } else if (index > this.itemSize - 1) {\n index = this.itemSize - 1;\n }\n }\n\n this._show(index);\n } else if (ev.type == 'panmove') {\n this._move(delta);\n }\n }\n });\n\n /**\n * @member ipu\n * 生成HammerCarousel实例,参数信息见{@link HammerCarousel#method-constructor}\n *\n * @param {String} slt\n * @param {Object} option\n * @returns {HammerCarousel}\n */\n ipu.hammerCarousel = function (slt, option) {\n return new HammerCarousel(slt, option);\n };\n})(ipu || window, jQuery, Hammer);\n\n(function (ipu, $) {\r\n\r\n function __dealCssEvent(eventNameArr, callback) {\r\n var events = eventNameArr,\r\n i, dom = this;// jshint ignore:line\r\n\r\n function fireCallBack(e) {\r\n /*jshint validthis:true */\r\n if (e.target !== this) return;\r\n callback.call(this, e);\r\n for (i = 0; i < events.length; i++) {\r\n dom.off(events[i], fireCallBack);\r\n }\r\n }\r\n\r\n if (callback) {\r\n for (i = 0; i < events.length; i++) {\r\n dom.on(events[i], fireCallBack);\r\n }\r\n }\r\n }\r\n\r\n $.fn.transitionEnd = function (callback) {\r\n __dealCssEvent.call(this, ['webkitTransitionEnd', 'transitionend'], callback);\r\n return this;\r\n };\r\n\r\n var _modalTemplateTempDiv = document.createElement('div');\r\n\r\n var defaults = {\r\n modalTitle: '',\r\n modalStack: true,\r\n modalButtonOk: '确定',\r\n modalButtonCancel: '取消',\r\n modalPreloaderTitle: '加载中',\r\n modalContainer: document.body ? document.body : 'body'\r\n };\r\n\r\n ipu.modalStack = [];\r\n\r\n ipu.modalStackClearQueue = function () {\r\n if (ipu.modalStack.length) {\r\n (ipu.modalStack.shift())();\r\n }\r\n };\r\n\r\n ipu.modal = function (params) {\r\n params = params || {};\r\n var buttonsHTML = '';\r\n if (params.buttons && params.buttons.length > 0) {\r\n for (var i = 0; i < params.buttons.length; i++) {\r\n buttonsHTML += '<span class=\"ipu-modal-button' + (params.buttons[i].bold ? ' ipu-modal-button-bold' : '') + '\">' + params.buttons[i].text + '</span>';\r\n }\r\n }\r\n var extraClass = params.extraClass || '';\r\n var titleHTML = params.title ? '<div class=\"ipu-modal-title\">' + params.title + '</div>' : '';\r\n var textHTML = params.text ? '<div class=\"ipu-modal-text\">' + params.text + '</div>' : '';\r\n var afterTextHTML = params.afterText ? params.afterText : '';\r\n var noButtons = !params.buttons || params.buttons.length === 0 ? 'ipu-modal-no-buttons' : '';\r\n var verticalButtons = params.verticalButtons ? 'ipu-modal-buttons-vertical' : '';\r\n\r\n var modalHTML = '<div class=\"ipu-modal ' + extraClass + ' ' + noButtons + '\"><div class=\"ipu-modal-inner\">' + (titleHTML + textHTML + afterTextHTML) + '</div><div class=\"ipu-modal-buttons ' + verticalButtons + '\">' + buttonsHTML + '</div></div>';\r\n\r\n _modalTemplateTempDiv.innerHTML = modalHTML;\r\n\r\n var modal = $(_modalTemplateTempDiv).children();\r\n\r\n $(defaults.modalContainer).append(modal[0]);\r\n\r\n // Add events on buttons\r\n modal.find('.ipu-modal-button').each(function (index, el) {\r\n $(el).on('click', function (e) {\r\n if (params.buttons[index].close !== false) ipu.closeModal(modal);\r\n if (params.buttons[index].onClick) params.buttons[index].onClick(modal, e);\r\n if (params.onClick) params.onClick(modal, index);\r\n });\r\n });\r\n ipu.openModal(modal);\r\n return modal[0];\r\n };\r\n\r\n /**\r\n * @member ipu\r\n * 弹出警告消息\r\n *\r\n * @param {String} text 警句文本\r\n * @param {String} title 警告标题,可选参数\r\n * @param {Function} callbackOk 用户确认后的回调函数,可选参数\r\n */\r\n ipu.alert = function (text, title, callbackOk) {\r\n if (typeof title === 'function') {\r\n callbackOk = arguments[1];\r\n title = undefined;\r\n }\r\n return ipu.modal({\r\n text: text || '',\r\n title: typeof title === 'undefined' ? defaults.modalTitle : title,\r\n buttons: [{text: defaults.modalButtonOk, bold: true, onClick: callbackOk}]\r\n });\r\n };\r\n\r\n /**\r\n * @member ipu\r\n * 弹出确认消息\r\n *\r\n * @param {String} text 确认文本\r\n * @param {String} title 确认标题,可选参数\r\n * @param {Function} callbackOk 用户确认后的回调函数,可选参数\r\n * @param {Function} callbackCancel 用户确认后的回调函数,可选参数\r\n */\r\n ipu.confirm = function (text, title, callbackOk, callbackCancel) {\r\n if (typeof title === 'function') {\r\n callbackCancel = arguments[2];\r\n callbackOk = arguments[1];\r\n title = undefined;\r\n }\r\n return ipu.modal({\r\n text: text || '',\r\n title: typeof title === 'undefined' ? defaults.modalTitle : title,\r\n buttons: [\r\n {text: defaults.modalButtonCancel, bold: true, onClick: callbackCancel},\r\n {text: defaults.modalButtonOk, bold: true, onClick: callbackOk}\r\n ]\r\n });\r\n };\r\n\r\n /**\r\n * @member ipu\r\n * 弹出输入框\r\n *\r\n * @param {String} text 输入提示文本\r\n * @param {String} title 输入提示标题,可选参数\r\n * @param {Function} callbackOk 用户确认后的回调函数,可选参数\r\n * @param {Function} callbackCancel 用户确认后的回调函数,可选参数\r\n */\r\n ipu.prompt = function (text, title, callbackOk, callbackCancel) {\r\n if (typeof title === 'function') {\r\n callbackCancel = arguments[2];\r\n callbackOk = arguments[1];\r\n title = undefined;\r\n }\r\n return ipu.modal({\r\n text: text || '',\r\n title: typeof title === 'undefined' ? defaults.modalTitle : title,\r\n afterText: '<input type=\"text\" class=\"ipu-modal-text-input\">',\r\n buttons: [\r\n {\r\n text: defaults.modalButtonCancel\r\n },\r\n {\r\n text: defaults.modalButtonOk,\r\n bold: true\r\n }\r\n ],\r\n onClick: function (modal, index) {\r\n if (index === 0 && callbackCancel) callbackCancel($(modal).find('.ipu-modal-text-input').val());\r\n if (index === 1 && callbackOk) callbackOk($(modal).find('.ipu-modal-text-input').val());\r\n }\r\n });\r\n };\r\n\r\n var minLoad = false; // 是否最小时间调用方式\r\n var loadOverTime = false; // 是否超过最小调用时间\r\n var loadEnd = false; // 是否调用结束\r\n var loadTimeOut = null; // 延时调用ID\r\n\r\n /**\r\n * @member ipu\r\n * 弹出加载消息提示\r\n *\r\n * @param {String} title 加载提示文本\r\n * @param {Number} minTime 消息最小显示时间,单位ms,可选参数\r\n */\r\n ipu.showPreloader = function (title, minTime) {\r\n ipu.hidePreloader(true);\r\n\r\n ipu.showPreloader.preloaderModal = ipu.modal({\r\n title: title || defaults.modalPreloaderTitle,\r\n text: '<div class=\"ipu-preloader\"></div>'\r\n });\r\n\r\n if (minTime) {\r\n minLoad = true;\r\n loadTimeOut = setTimeout(function () {\r\n loadOverTime = true;\r\n if (loadEnd) {\r\n ipu.hidePreloader();\r\n }\r\n }, minTime);\r\n }\r\n\r\n return ipu.showPreloader.preloaderModal;\r\n };\r\n\r\n /**\r\n * @member ipu\r\n * 隐藏加载消息提示\r\n *\r\n * @param {Boolean} force 是否强制隐藏,不管最小提示时间,可选\r\n */\r\n ipu.hidePreloader = function (force) {\r\n if (force || !minLoad || (minLoad && loadOverTime)) {\r\n if (force && loadTimeOut) {\r\n window.clearTimeout(loadTimeOut);\r\n }\r\n ipu.showPreloader.preloaderModal && ipu.closeModal(ipu.showPreloader.preloaderModal);\r\n minLoad = false; // 重置各标志位\r\n loadOverTime = false;\r\n loadEnd = false;\r\n loadTimeOut = null;\r\n } else {\r\n loadEnd = true;\r\n }\r\n };\r\n\r\n /**\r\n * @member ipu\r\n * 显示加载状态\r\n */\r\n ipu.showIndicator = function () {\r\n if ($('.ipu-preloader-indicator-modal')[0]) return;\r\n $(defaults.modalContainer).append('<div class=\"ipu-preloader-indicator-overlay\"></div><div class=\"ipu-preloader-indicator-modal\"><span class=\"ipu-preloader ipu-preloader-white\"></span></div>');\r\n };\r\n\r\n /**\r\n * @member ipu\r\n * 隐藏加载状态\r\n */\r\n ipu.hideIndicator = function () {\r\n $('.ipu-preloader-indicator-overlay, .ipu-preloader-indicator-modal').remove();\r\n };\r\n\r\n /**\r\n * @member ipu\r\n * 显示操作选项\r\n *\r\n * @param{[[Object]]} actions\r\n * @param {Object} actions.Object\r\n * @param {String} actions.Object.text 操作名称\r\n * @param {Boolean} actions.Object.label 是否标签,非标签就是操作项,操作项有后续的配置,标签项无须后续配置项\r\n * @param {String:warning} actions.Object.color 样式,可选\r\n * @param {String:warning} actions.Object.bg 背景样式,可选\r\n * @param {Function} actions.Object.onClick 点击时回调函数\r\n */\r\n ipu.actions = function (params) {\r\n var modal, groupSelector, buttonSelector;\r\n params = params || [];\r\n\r\n if (params.length > 0 && !$.isArray(params[0])) {\r\n params = [params];\r\n }\r\n var modalHTML;\r\n var buttonsHTML = '';\r\n for (var i = 0; i < params.length; i++) {\r\n for (var j = 0; j < params[i].length; j++) {\r\n if (j === 0) buttonsHTML += '<div class=\"ipu-actions-modal-group\">';\r\n var button = params[i][j];\r\n var buttonClass = button.label ? 'ipu-actions-modal-label' : 'ipu-actions-modal-button';\r\n if (button.bold) buttonClass += ' ipu-actions-modal-button-bold';\r\n if (button.color) buttonClass += ' ipu-color-' + button.color;\r\n if (button.bg) buttonClass += ' ipu-bg-' + button.bg;\r\n if (button.disabled) buttonClass += ' disabled';\r\n buttonsHTML += '<span class=\"' + buttonClass + '\">' + button.text + '</span>';\r\n if (j === params[i].length - 1) buttonsHTML += '</div>';\r\n }\r\n }\r\n modalHTML = '<div class=\"ipu-actions-modal\">' + buttonsHTML + '</div>';\r\n _modalTemplateTempDiv.innerHTML = modalHTML;\r\n modal = $(_modalTemplateTempDiv).children();\r\n $(defaults.modalContainer).append(modal[0]);\r\n groupSelector = '.ipu-actions-modal-group';\r\n buttonSelector = '.ipu-actions-modal-button';\r\n\r\n var groups = modal.find(groupSelector);\r\n groups.each(function (index, el) {\r\n var groupIndex = index;\r\n $(el).children().each(function (index, el) {\r\n var buttonIndex = index;\r\n var buttonParams = params[groupIndex][buttonIndex];\r\n var clickTarget;\r\n if ($(el).is(buttonSelector)) clickTarget = $(el);\r\n // if (toPopover && $(el).find(buttonSelector).length > 0) clickTarget = $(el).find(buttonSelector);\r\n\r\n if (clickTarget) {\r\n clickTarget.on('click', function (e) {\r\n if (buttonParams.close !== false) ipu.closeModal(modal);\r\n if (buttonParams.onClick) buttonParams.onClick(modal, e);\r\n });\r\n }\r\n });\r\n });\r\n ipu.openModal(modal);\r\n return modal[0];\r\n };\r\n\r\n //显示一个消息,会在2秒钟后自动消失\r\n /**\r\n * @member ipu\r\n * 悬浮提示消息\r\n *\r\n * @param {String} msg 消息文本\r\n * @param {Number} duration=2000 消息显示时间,单位ms\r\n */\r\n ipu.toast = function (msg, duration, extraclass) {\r\n var $toast = $('<div class=\"ipu-modal ipu-toast ' + (extraclass || '') + '\">' + msg + '</div>').appendTo(document.body);\r\n ipu.openModal($toast, function () {\r\n setTimeout(function () {\r\n ipu.closeModal($toast);\r\n }, duration || 2000);\r\n });\r\n };\r\n\r\n ipu.openModal = function (modal, cb) {\r\n modal = $(modal);\r\n var isModal = modal.hasClass('ipu-modal'),\r\n isNotToast = !modal.hasClass('ipu-toast');\r\n isNotToast = false; // 强制打开新窗口\r\n\r\n if ($('.ipu-modal.ipu-modal-in:not(.ipu-modal-out)').length && defaults.modalStack && isModal && isNotToast) {\r\n ipu.modalStack.push(function () {\r\n ipu.openModal(modal, cb);\r\n });\r\n return;\r\n }\r\n\r\n var isPopup = modal.hasClass('ipu-popup');\r\n var isLoginScreen = modal.hasClass('ipu-login-screen');\r\n var isPickerModal = modal.hasClass('ipu-picker-modal');\r\n var isToast = modal.hasClass('ipu-toast');\r\n\r\n if (isModal) {\r\n modal.show();\r\n modal.css({\r\n marginTop: -Math.round(modal.outerHeight() / 2) + 'px'\r\n });\r\n }\r\n\r\n if (isToast) {\r\n modal.css({\r\n marginLeft: -Math.round(modal.outerWidth() / 2) + 'px' //1.185 是初始化时候的放大效果\r\n });\r\n }\r\n\r\n var overlay;\r\n if (!isLoginScreen && !isPickerModal && !isToast) {\r\n if ($('.ipu-modal-overlay').length === 0 && !isPopup) {\r\n $(defaults.modalContainer).append('<div class=\"ipu-modal-overlay\"></div>');\r\n }\r\n if ($('.ipu-popup-overlay').length === 0 && isPopup) {\r\n $(defaults.modalContainer).append('<div class=\"ipu-popup-overlay\"></div>');\r\n }\r\n overlay = isPopup ? $('.ipu-popup-overlay') : $('.ipu-modal-overlay');\r\n }\r\n\r\n //Make sure that styles are applied, trigger relayout;\r\n var clientLeft = modal[0].clientLeft;\r\n\r\n // Trugger open event\r\n modal.trigger('open');\r\n\r\n // Picker modal body class\r\n if (isPickerModal) {\r\n $(defaults.modalContainer).addClass('ipu-with-picker-modal');\r\n }\r\n\r\n // Classes for transition in\r\n if (!isLoginScreen && !isPickerModal && !isToast) {\r\n overlay.addClass('ipu-modal-overlay-visible');\r\n }\r\n modal.removeClass('ipu-modal-out').addClass('ipu-modal-in').transitionEnd(function (e) {\r\n if (modal.hasClass('ipu-modal-out')) modal.trigger('closed');\r\n else modal.trigger('opened');\r\n });\r\n // excute callback\r\n if (typeof cb === 'function') {\r\n cb.call(this);\r\n }\r\n return true;\r\n };\r\n\r\n ipu.closeModal = function (modal) {\r\n modal = $(modal || '.ipu-modal-in');\r\n if (typeof modal !== 'undefined' && modal.length === 0) {\r\n return;\r\n }\r\n var isModal = modal.hasClass('ipu-modal'),\r\n isPopup = modal.hasClass('ipu-popup'),\r\n isToast = modal.hasClass('ipu-toast'),\r\n isLoginScreen = modal.hasClass('ipu-login-screen'),\r\n isPickerModal = modal.hasClass('ipu-picker-modal'),\r\n removeOnClose = modal.hasClass('ipu-remove-on-close'),\r\n overlay = isPopup ? $('.ipu-popup-overlay') : $('.ipu-modal-overlay');\r\n if (isPopup) {\r\n if (modal.length === $('.ipu-popup.ipu-modal-in').length) {\r\n overlay.removeClass('ipu-modal-overlay-visible');\r\n }\r\n }\r\n else if (!(isPickerModal || isToast)) {\r\n overlay.removeClass('ipu-modal-overlay-visible');\r\n }\r\n modal.trigger('close');\r\n\r\n // Picker modal body class\r\n if (isPickerModal) {\r\n $(defaults.modalContainer).removeClass('ipu-with-picker-modal');\r\n $(defaults.modalContainer).addClass('ipu-picker-modal-closing');\r\n }\r\n\r\n modal.removeClass('ipu-modal-in').addClass('ipu-modal-out').transitionEnd(function (e) {\r\n if (modal.hasClass('ipu-modal-out')) modal.trigger('closed');\r\n else modal.trigger('opened');\r\n\r\n if (isPickerModal) {\r\n $(defaults.modalContainer).removeClass('ipu-picker-modal-closing');\r\n }\r\n if (isPopup || isLoginScreen || isPickerModal) {\r\n modal.removeClass('ipu-modal-out').hide();\r\n if (removeOnClose && modal.length > 0) {\r\n modal.remove();\r\n }\r\n }\r\n else {\r\n modal.remove();\r\n }\r\n });\r\n if (isModal && defaults.modalStack) {\r\n ipu.modalStackClearQueue();\r\n }\r\n\r\n return true;\r\n };\r\n\r\n function handleClicks(e) {\r\n /*jshint validthis:true */\r\n var clicked = $(this);\r\n var url = clicked.attr('href');\r\n\r\n\r\n //Collect Clicked data- attributes\r\n /* var clickedData = clicked.dataset();\r\n\r\n // Popup\r\n var popup;\r\n if (clicked.hasClass('ipu-open-popup')) {\r\n if (clickedData.popup) {\r\n popup = clickedData.popup;\r\n }\r\n else popup = '.ipu-popup';\r\n ipu.popup(popup);\r\n }\r\n if (clicked.hasClass('ipu-close-popup')) {\r\n if (clickedData.popup) {\r\n popup = clickedData.popup;\r\n }\r\n else popup = '.ipu-popup.modal-in';\r\n ipu.closeModal(popup);\r\n }*/\r\n\r\n // Close Modal\r\n if (clicked.hasClass('ipu-modal-overlay')) {\r\n if ($('.ipu-modal.ipu-modal-in').length > 0 && defaults.modalCloseByOutside)\r\n ipu.closeModal('.ipu-modal.ipu-modal-in');\r\n if ($('.ipu-actions-modal.ipu-modal-in').length > 0 && defaults.actionsCloseByOutside)\r\n ipu.closeModal('.ipu-actions-modal.ipu-modal-in');\r\n\r\n }\r\n if (clicked.hasClass('ipu-popup-overlay')) {\r\n if ($('.ipu-popup.ipu-modal-in').length > 0 && defaults.popupCloseByOutside)\r\n ipu.closeModal('.ipu-popup.modal-in');\r\n }\r\n }\r\n\r\n $(document).on('click', ' .ipu-modal-overlay, .ipu-popup-overlay, .ipu-close-popup, .ipu-open-popup, .ipu-close-picker', handleClicks);\r\n})(ipu || window, jQuery);\r\n\n(function (ipu, $) {\r\n /**\r\n * @class 导航切换组件\r\n *\r\n * @example\r\n *\r\n * <!-- 组件的html分成导航和内容两部分,一般与flex栅格配合布局-->\r\n *\r\n * <!-- 组件导航部分 -->\r\n * <nav class=\"ipu-navbar \">\r\n * <a class=\"ipu-navbar-item \" href=\"javascript:;\">\r\n * <span class=\"ipu-icon fa fa-home\"></span>\r\n * <span class=\"ipu-navbar-item-label\">插件</span>\r\n * </a>\r\n * <a class=\"ipu-navbar-item \" href=\"javascript:;\">\r\n * <span class=\"ipu-icon fa fa-dashcube\"></span>\r\n * <span class=\"ipu-navbar-item-label\">JS组件</span>\r\n * </a>\r\n * <a class=\"ipu-navbar-item ipu-current\" href=\"javascript:;\">\r\n * <span class=\"ipu-icon fa fa-map\"></span>\r\n * <span class=\"ipu-navbar-item-label\">静态组件</span>\r\n * </a>\r\n * <a class=\"ipu-navbar-item\" href=\"javascript:;\">\r\n * <span class=\"ipu-icon fa fa-mortar-board\"></span>\r\n * <span class=\"ipu-navbar-item-label\">更多</span>\r\n * </a>\r\n * </nav>\r\n *\r\n * <!-- 内容部分 -->\r\n * <div class=\"ipu-nav-content\">\r\n * <ul>\r\n * <li>\r\n * 自定义内容1\r\n * </li>\r\n * <li>\r\n * 自定义内容\r\n * </li>\r\n * <li>\r\n * 自定义内容\r\n * </li>\r\n * <li>\r\n * 自定义内容\r\n * </li>\r\n * </ul>\r\n * </div>\r\n *\r\n *\r\n * @constructor 不能直接访问该类,调用{@link ipu#navBar ipu.navBar(slt, option)}生成实例\r\n * @param {String|jqueryObj} slt jquery选择器字符串或jquery对象,用来查找要被组件初始化化的dom\r\n * @param {Object} option 组件配置参数,默认配置见 {@link #cfg-defaultOption}\r\n */\r\n function NavBar(slt, option) {\r\n this.option = $.extend({}, this.defaultOption, option);\r\n this.content = $(this.option.contentSlt);\r\n this.nav = $(slt);\r\n this.wrapper = $(\">ul\", this.content);\r\n this.contents = $(\">li\", this.wrapper);\r\n this.navs = $(\">a\", this.nav);\r\n var me = this;\r\n\r\n var activeIndex = this.navs.filter(\".ipu-current\").index(); // 查找默认有active的索引\r\n if (activeIndex == -1) {\r\n activeIndex = this.contents.filter(\".ipu-current\").index(); // 查找默认有active的索引\r\n }\r\n this.option.index = activeIndex != -1 ? activeIndex : 0;\r\n\r\n if (!this.option.animate) {\r\n this.wrapper.addClass(\"ipu-no-animation\")\r\n }\r\n\r\n this.navs.each(function (index, i) {\r\n $(this).click(function () {\r\n me.show(index);\r\n });\r\n });\r\n\r\n this.lastIndex = null;\r\n this.currentIndex = null;\r\n me.show(this.option.index);\r\n }\r\n\r\n /**\r\n * 组件默认配置项\r\n *\r\n * @cfg {Object} defaultOption\r\n * @cfg {Boolean} defaultOption.animate=false 切换时是否添加动画效果\r\n * @cfg {Dom|String|JqueryObj} defaultOption.contentSlt='.ipu-nav-content' 内容dom选择器,页面有多个navBar组件时,需要设置此值\r\n * @cfg {Function} defaultOption.callBack 切换时的回调函数\r\n * @cfg {Number} defaultOption.callBack.index 当前显示项索引\r\n */\r\n NavBar.prototype.defaultOption = {\r\n animate: false,\r\n contentSlt: \".ipu-nav-content\",\r\n callBack: function (currentIndex, lastIndex) {\r\n }\r\n };\r\n\r\n /**\r\n * 显示第几项内容\r\n * @param {Number} index 显示内容项索引\r\n */\r\n NavBar.prototype.show = function (index) {\r\n if (this.currentIndex != index) {\r\n $(this.contents[index]).addClass(\"ipu-show\");\r\n\r\n if (this.option.animate) {\r\n if (this.lastIndex != null && this.lastIndex != index) {\r\n $(this.contents[this.lastIndex]).removeClass(\"ipu-show\"); // 隐藏上上个元素\r\n }\r\n\r\n if (this.currentIndex != null) { // 非第一次需要动画效果\r\n if (this.currentIndex < index) { // 需要内容为往左走,显示右边的内容\r\n if (this.lastIndex != null && this.lastIndex < this.currentIndex) { // 内容已经左走过了,则需要移除动画复原位置,再通过width()方法强制生效\r\n this.wrapper.addClass(\"ipu-no-animation\").removeClass(\"ipu-nav-content-right\").width(); // 可以强制刷新,默认jquery应该会将这些dom上的修改延时处理?\r\n }\r\n } else {\r\n if (this.lastIndex == null || this.lastIndex > this.currentIndex) { // 类似同上\r\n this.wrapper.addClass(\"ipu-no-animation\").addClass(\"ipu-nav-content-right\").width(); // 可以强制刷新不?\r\n }\r\n }\r\n this.wrapper.removeClass(\"ipu-no-animation\").toggleClass(\"ipu-nav-content-right\");\r\n }\r\n } else {\r\n $(this.contents[this.currentIndex]).removeClass(\"ipu-show\");\r\n }\r\n\r\n // 更新class,ipu-current状态\r\n $(this.contents[index]).addClass(\"ipu-current\").siblings(\".ipu-current\").removeClass(\"ipu-current\");\r\n $(this.navs[index]).addClass(\"ipu-current\").siblings(\".ipu-current\").removeClass(\"ipu-current\");\r\n\r\n this.lastIndex = this.currentIndex;\r\n this.currentIndex = index;\r\n\r\n if (this.option.callBack) {\r\n this.option.callBack(this.currentIndex, this.lastIndex);\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * @member ipu\r\n * 生成NavBar实例,参数信息见{@link NavBar#method-constructor}\r\n *\r\n * @param {String} slt\r\n * @param {Object} option\r\n * @returns {NavBar}\r\n */\r\n ipu.navBar = function (slt, option) {\r\n return new NavBar(slt, option);\r\n };\r\n})(ipu || window, jQuery);\r\n\n(function (ipu, $) {\r\n function __dealCssEvent(eventNameArr, callback) {\r\n var events = eventNameArr,\r\n i, dom = this;// jshint ignore:line\r\n\r\n function fireCallBack(e) {\r\n if (e.target !== this) return;\r\n callback.call(this, e);\r\n for (i = 0; i < events.length; i++) {\r\n dom.off(events[i], fireCallBack);\r\n }\r\n }\r\n\r\n if (callback) {\r\n for (i = 0; i < events.length; i++) {\r\n dom.on(events[i], fireCallBack);\r\n }\r\n }\r\n }\r\n\r\n $.fn.animationEnd = function (callback) {\r\n __dealCssEvent.call(this, ['webkitAnimationEnd', 'animationend'], callback);\r\n return this;\r\n };\r\n\r\n function submitForm(doc, url, params) {\r\n var form = doc.createElement(\"form\");\r\n form.action = url;\r\n form.method = \"post\";\r\n form.style.display = \"none\";\r\n\r\n for (var x in params) {\r\n var ele = doc.createElement(\"input\");\r\n ele.type = \"hidden\";\r\n ele.name = x;\r\n ele.value = params[x];\r\n form.appendChild(ele);\r\n }\r\n\r\n doc.body.appendChild(form);\r\n form.submit();\r\n }\r\n\r\n // 检查是否有ipu-pages的结构\r\n function checkPages() {\r\n if (!hasPages) {\r\n pagesObj = $(\".ipu-pages\"); // pagesObj为空则进行jquery取值\r\n if (pagesObj.size() == 0) {\r\n pagesObj = $(\"<div class='ipu-pages'><div class='ipu-page ipu-show \" + zeroPageClass + \"' id='\" + pageIdPrefix + \"0'></div>\").appendTo(\"body\");\r\n }\r\n hasPages = true;\r\n }\r\n }\r\n\r\n // 站位页面\r\n function isZeroPage(page) {\r\n return $(page).hasClass(zeroPageClass);\r\n }\r\n\r\n var page = {};\r\n var hasPages = false;\r\n var maps = {};\r\n var pageNo = 1; // 编号0留给主页面或当前页面,或没有\r\n var pageIdPrefix = \"ipuPage-\";\r\n var pagesObj = null;\r\n var animateInClass = \"ipu-anim ipu-slideRightIn\";\r\n var animateOutClass = \"ipu-anim ipu-slideRightOut\";\r\n var eventName = \"ipuUIPageBack\";\r\n var zeroPageClass = 'ipu-page-zero'; // 占位页面,对于为当前页面\r\n var zeroPagesClass = 'ipu-pages-zero'; // 占位页面的特殊class,作用已忘记,应该是用来标记显示用\r\n\r\n /**\r\n * @private\r\n * @class page 单页面实现功能对象\r\n * 以iframe加载子页面的方式,页面后退(后退时,后退到a页面,所有在a页面后打开的页面全都关闭)\r\n * ipu框架在浏览器运行时,使用此对象实现与客户端运行类似的效果\r\n * 大致实现是当前页面进行处理,所有的后续页面加载都放在一个iframe中,所有页面按加载顺序排序,关闭或后退按页面打开的顺序处理\r\n */\r\n\r\n\r\n /**\r\n * 组件默认配置项\r\n *\r\n * @cfg {Object} defaultOption page组件默认配置项\r\n * @cfg {Window} defaultOption.target = window.parent 默认执行的窗口对象,子页面调用相关方法,默认都都是在parent窗口执行,需要指定此参数,如顶层父窗口\r\n * @cfg {Number} defaultOption.backIndex=-1 回退索引,大于0时,正序计算,小于0时,倒序计算,-1即为当页面的上一个页面\r\n * @cfg {Number} defaultOption.closeIndex 关闭页面索引,参数说明同上\r\n * @cfg {Object} defaultOption.params Json格式参数,POST方式打开页面时,使用此参数传递参数,暂不支持数组格式参数\r\n * @cfg {Boolean} defaultOption.animate=true 是否使用动画,打开或回退页面时有效参数\r\n * @cfg {Boolean} defaultOption.showLoading=true 是否显示加载提示,打开或回退页面时有效参数\r\n * @cfg {Boolean} defaultOption.loadingMessage='正在加载中' 是否显示加载提示,打开或回退页面时有效参数\r\n * @cfg defaultOption.data=null 回退页面时,传递给回退到的页面的参数,回退到的页面有设置监听函数时,监听函数可以接收此参数\r\n * @cfg {String} defaultOption.pageName='' 页面的名称,打开或回退页面时有效参数\r\n * @cfg {Number} defaultOption.pageMax='' 保留的最大页面数,大于2\r\n * @cfg {Function} defaultOption.callBack 方法执行结束时的回调函数\r\n */\r\n page.defaultOption = { // 那个窗口执行open,默认父窗口\r\n target: window.parent, // 默认执行父窗口,方法:all\r\n backIndex: -1, // 默认回退一页 方法:back\r\n closeIndex: -1, // 默认关闭最近一个页面 方法:close\r\n params: {}, // post的传参 方法:post\r\n animate: true, // 是否动画效果 方法:open post\r\n showLoading: true, // 是否显示加载消息 方法:open post\r\n loadingMessage: '正在加载中', // 方法:open post\r\n method: null, // 请求方式,内置参数,方法自己设置,用户不需要设置 方法:无\r\n minMessageTime: 500, // 最小显示加载时间,避免出现闪现的情况 方法:open post\r\n data: null, // 回退时,回传参数, 方法:back\r\n pageName: '', // 给打开的页面命名,以便根据此页面名称来切换页面 方法:open post back close\r\n pageMax: 6, // 允许的最大打开页面数\r\n callBack: function () { // 事件回调 方法:open post close back\r\n }\r\n };\r\n\r\n // 新增限制最大页面数\r\n page.limitPages = function () {\r\n var pageMax = this.defaultOption.pageMax - 2; //\r\n $(\".ipu-page.ipu-show\").prevAll(\".ipu-page:gt(\" + pageMax + \")\").remove();\r\n };\r\n\r\n // 当前页面加载,针对顶层父窗口\r\n page.openPage = function (url, option) {\r\n var newPage = null;\r\n var nowPageNo = pageIdPrefix + (pageNo++);\r\n maps[nowPageNo] = url;\r\n\r\n checkPages();\r\n\r\n if (option.showLoading) {\r\n ipu.showPreloader(option.loadingMessage, option.minMessageTime);\r\n }\r\n\r\n if (option.method == 'post') {\r\n newPage = $(\"<div class='ipu-page' id='\" + nowPageNo + \"' data-name='\" + option.pageName + \"'><iframe class='ipu-page-iframe'></iframe></div>\");\r\n } else {\r\n newPage = $(\"<div class='ipu-page' id='\" + nowPageNo + \"' data-name='\" + option.pageName + \"'><iframe class='ipu-page-iframe' src='\" + url + \"'></iframe></div>\");\r\n }\r\n\r\n var zeroPage = isZeroPage($(\".ipu-page:last\", pagesObj));\r\n var animatePage = newPage;\r\n if (zeroPage) {\r\n animatePage = pagesObj.addClass(zeroPagesClass);\r\n }\r\n\r\n function end() {\r\n if (option.showLoading) {\r\n ipu.hidePreloader();\r\n }\r\n\r\n if (option.animate) {\r\n console.log(\"--\" + nowPageNo);\r\n animatePage.removeClass(animateInClass);\r\n }\r\n\r\n newPage.siblings(\".ipu-show\").removeClass('ipu-show');\r\n if (option.callBack) {\r\n option.callBack();\r\n }\r\n\r\n // 新增限制最大页面数\r\n page.limitPages();\r\n }\r\n\r\n $(\".ipu-page-iframe\", newPage).one('load', function () {\r\n newPage.addClass(\"ipu-show\").width(); // 强制生效,否则可能出现页面闪现,无动画情况\r\n\r\n if (zeroPage) {\r\n animatePage.removeClass(zeroPagesClass);\r\n }\r\n if (option.animate) {\r\n animatePage.addClass(animateInClass).animationEnd(end);\r\n } else {\r\n end();\r\n }\r\n });\r\n\r\n newPage.appendTo(pagesObj);\r\n if (option.method == 'post') {\r\n var pageDoc = $(\".ipu-page-iframe\", newPage)[0].contentDocument;\r\n submitForm(pageDoc, url, option.params);\r\n }\r\n };\r\n\r\n // post方式加载页面\r\n page.postPage = function (url, option) {\r\n option.method = 'post';\r\n page.openPage(url, option);\r\n };\r\n\r\n // 当前页面后退,针对顶层父窗口\r\n page.backPage = function (option) {\r\n var backIndex = option.backIndex;\r\n var page = null;\r\n var nowPage = $(\".ipu-page.ipu-show\", pagesObj);\r\n\r\n if (option.pageName) {\r\n page = $(\".ipu-page[data-name='\" + option.pageName + \"']:first\", pagesObj);\r\n } else if (backIndex == 0) {\r\n page = $(\".ipu-page:first\", pagesObj);\r\n } else { // 越界的情况\r\n var prevPage = nowPage.prevAll(\".ipu-page\");\r\n if (backIndex < 0) {\r\n page = $(prevPage[-backIndex - 1]);\r\n } else {\r\n page = $(prevPage[prevPage.size() - backIndex]);\r\n }\r\n }\r\n\r\n var animatePage = nowPage;\r\n var zeroPage = isZeroPage(page);\r\n\r\n // 主页面模式时\r\n if (zeroPage) {\r\n animatePage = pagesObj;\r\n } else {\r\n page.addClass(\"ipu-show\"); //显示前一个\r\n }\r\n\r\n function end() {\r\n $(this).removeClass(animateOutClass);\r\n page.nextAll(\".ipu-page\").remove();\r\n\r\n var iframe = $(\".ipu-page-iframe\", page);\r\n var nowDoc;\r\n\r\n if (iframe.size() == 0) { // 找不到子窗口就当是返回了主页面,在当前窗口触发\r\n nowDoc = window.document;\r\n } else {\r\n nowDoc = iframe[0].contentDocument;\r\n }\r\n\r\n if (zeroPage) {\r\n pagesObj.addClass(zeroPagesClass);\r\n }\r\n\r\n var evt = nowDoc.createEvent('Event');\r\n evt.initEvent(eventName, true, true);\r\n if (option.data) {\r\n evt.data = option.data;\r\n }\r\n nowDoc.body.dispatchEvent(evt);\r\n if (option.callBack) {\r\n option.callBack();\r\n }\r\n }\r\n\r\n if (option.animate) {\r\n animatePage.addClass(animateOutClass).animationEnd(end);\r\n } else {\r\n end();\r\n }\r\n };\r\n\r\n // 往前关闭窗口\r\n page.closePage = function (option) {\r\n var closeIndex = option.closeIndex;\r\n var prevPage = $(\".ipu-page.ipu-show\", pagesObj).prevAll(\".ipu-page\");\r\n\r\n if (option.pageName) {\r\n closeIndex = $(\".ipu-page[data-name='\" + option.pageName + \"']:first\", pagesObj).index();\r\n } else if (closeIndex < 0) {\r\n closeIndex = -closeIndex - 1;\r\n } else {\r\n closeIndex = prevPage.size() - closeIndex;\r\n }\r\n\r\n $(prevPage[closeIndex]).remove();\r\n if (option.callBack) {\r\n option.callBack();\r\n }\r\n };\r\n\r\n /**\r\n * get请求的方式加载页面\r\n *\r\n * @param {String} url\r\n * @param {Object} option 回退参数,见{@link #cfg-defaultOption}\r\n */\r\n page.open = function (url, option) {\r\n option = $.extend({}, this.defaultOption, option);\r\n option.target.ipu.page.openPage(url, option);\r\n };\r\n\r\n /**\r\n * 使用post方式加载一个新页面\r\n *\r\n * @param {String} url 要打开的页面地址\r\n * @param {Object} option 回退参数,见{@link #cfg-defaultOption}\r\n */\r\n page.post = function (url, option) {\r\n option = $.extend({}, this.defaultOption, option);\r\n option.method = 'post';\r\n option.target.ipu.page.openPage(url, option);\r\n };\r\n\r\n /**\r\n * 回退到某个历史页面,可以根据pageName回退,也可根据backIndex回退,默认回退上一个页面\r\n *\r\n * @param {Object} option 回退参数,见{@link #cfg-defaultOption}\r\n */\r\n page.back = function (option) {\r\n option = $.extend({}, this.defaultOption, option);\r\n option.target.ipu.page.backPage(option);\r\n };\r\n\r\n /**\r\n * 回退到首页\r\n *\r\n * @param {Object} option 回退参数,见{@link #cfg-defaultOption}\r\n */\r\n page.backHome = function (option) {\r\n option = option || {};\r\n option.backIndex = 0;\r\n page.back(option);\r\n };\r\n\r\n // 子窗口,待确认\r\n page.close = function (option) {\r\n option = $.extend({}, this.defaultOption, option);\r\n option.target.ipu.page.closePage(option);\r\n };\r\n\r\n /**\r\n * 给页面增加一个监听,从其它页面回退到此页面,调用此函数,可以接收其它页面传来的数据\r\n *\r\n * @param {Function} back 监听函数\r\n * @param back.data 其它页面传过来的参数,推荐字符串或Json对象\r\n */\r\n page.onBack = function (back) {\r\n $(\"body\").on(eventName, function (e) {\r\n var data = e.originalEvent.data;\r\n back(data);\r\n });\r\n };\r\n\r\n // 提供一个关闭一群窗口的方法\r\n ipu.page = page;\r\n})(ipu || window, jQuery);\r\n\n// picker\r\n(function (ipu, $, Hammer) {\r\n var showItemSize = 9; // 显示的子项数量,\r\n var r = 90; // 计算旋转的圆半径,结果应该缩小,是为了r不要距离容器太近,是否不应该设置px,使用rem\r\n var itemAngle = 180 / showItemSize; // 每项对应的角度是 180/9 = 20\r\n var maxExceed = itemAngle; // 滚动时允许超出边界的最大角度,允许最多翻过一项\r\n // itemHeight = 40px;每项数据的高度设置 // 需要给出r=89是怎么计算出来的,是根据 40/2/Math.tan(40/2/180*Math.PI)=113,直接太大不好看\r\n\r\n\r\n function toRem(num) {\r\n return num / 100;\r\n }\r\n\r\n /**\r\n * @private\r\n * @class 选择器,被DtPicker和PopPicker使用,实现选择与滚动等基础功能\r\n *\r\n * @constructor 初始化方法\r\n * @param {String|DOM|JQueryObj} slt\r\n * @param {object} option 组件参数,默认配置见 {@link #cfg-defaultOption}\r\n */\r\n function Picker(slt, option) {\r\n this.el = $(slt)[0];\r\n this.option = $.extend({}, this.defaultOption, option);\r\n this._init();\r\n }\r\n\r\n /**\r\n * 组件默认配置项\r\n *\r\n * @cfg {Object} defaultOption=\r\n * @cfg {Boolean} defaultOption.listen=true 是否需要监听变化\r\n * @cfg {[Object]} defaultOption.data=[] 可选择项数组,每个项须有text属性\r\n * @cfg {String} defaultOption.data.text 子项展示文本\r\n * @cfg {Function} defaultOption.onChange=null 选择变化时的回调函数\r\n * @cfg {Object} defaultOption.onChange.sltItem 选中项\r\n * @cfg {Number} defaultOption.onChange.newIndex 新的选中项索引\r\n * @cfg {Number} defaultOption.onChange.oldIndex 旧的选中项索引\r\n * @cfg {Boolean} defaultOption.onChange.newData 是否为调用setItem()方法触发\r\n */\r\n Picker.prototype.defaultOption = {\r\n listen: true,\r\n data: [],\r\n onChange: null\r\n };\r\n\r\n Picker.prototype._init = function () {\r\n var self = this;\r\n this.wrap = $(\">ul\", this.el);\r\n this.index = null; // 选中项索引\r\n this.listen = !!this.option.listen;\r\n\r\n this.beginAngle = 0; // 开始角度\r\n this.beginExceed = this.beginAngle - maxExceed; // 最小角度值\r\n this.stopInertiaMove = false;\r\n this.lastAngle = null; // 保存滑动前的角度 // 当前滚动的角度\r\n\r\n // 如果是ios,则ul的旋转中心点,样式不同于android\r\n if (ipu.device.ios) {\r\n this.wrap.css(\"transform-origin\", \"center center \" + toRem(r) + \"rem\"); //如果是ios,要变更旋转的中心点\r\n }\r\n\r\n\r\n this.setItems(this.option.data);\r\n\r\n this.hammer = new Hammer.Manager(this.el);\r\n this.hammer.add(new Hammer.Pan({direction: Hammer.DIRECTION_VERTICAL, threshold: 5}));\r\n this.hammer.add(new Hammer.Press({threshold: 4})); //\r\n this.hammer.on(\"panstart panmove panend pancancel\", Hammer.bindFn(this._onPan, this));\r\n\r\n // 处理滚动中,用户点中某项,停止\r\n this.hammer.on(\"press pressup\", function (e) { // 如果用户点击了,是停止自动滚动\r\n if (this.empty) {\r\n return;\r\n }\r\n\r\n self.stopInertiaMove = true;\r\n if (e.type == 'pressup') {\r\n self.endScroll();\r\n }\r\n });\r\n };\r\n\r\n /**\r\n * 设置选择项\r\n *\r\n * @param {[Object]} data 设置项数组\r\n */\r\n Picker.prototype.setItems = function (data, textName) { // textNam字体暂不支持\r\n this.wrap.empty(); // 清空历史数据\r\n this.data = data = data || [];\r\n this.empty = data.length == 0; // 数据是否为空\r\n\r\n this.newData = true; // 是否为新设置数据标记\r\n var self = this;\r\n var lis = \"\";\r\n textName = textName || 'text';\r\n\r\n for (var i = 0, j = data.length; i < j; i++) {\r\n lis = lis + \"<li>\" + data[i][textName] + \"</li>\";\r\n }\r\n\r\n $(lis).appendTo(this.wrap);\r\n\r\n this.items = $(\">li\", this.wrap);\r\n this.itemsSize = this.items.size();\r\n\r\n this.endAngle = (this.empty ? 0 : this.itemsSize - 1) * itemAngle;\r\n this.endExceed = this.endAngle + maxExceed; // 最大旋转角度值\r\n\r\n // 初始化各子项角度\r\n this.items.each(function (i) {\r\n $(this).css({\r\n \"transform\": \"translateZ(\" + toRem(r) + \"rem) rotateX(-\" + (i * itemAngle) + \"deg)\",\r\n \"transform-origin\": \"center center -\" + toRem(r) + \"rem\"\r\n });\r\n $(this).click(function () {\r\n self.stopInertiaMove = true;\r\n self.setAngle(i * itemAngle, true);\r\n })\r\n });\r\n\r\n var newAngle;\r\n if (this.empty || this.index == null) {\r\n newAngle = 0;\r\n } else {\r\n if (this.index > this.itemsSize - 1) { // 取最大值\r\n newAngle = (this.itemsSize - 1) * itemAngle;\r\n } else {\r\n newAngle = this.index * itemAngle;\r\n }\r\n }\r\n this.setAngle(newAngle, true);\r\n };\r\n\r\n Picker.prototype._onPan = function (ev) {\r\n if (this.empty) {\r\n return;\r\n }\r\n\r\n //console.log(ev.deltaX + \"==\"+ ev.deltaY);\r\n if (ev.type == 'panstart') { // 好像一定要移动才有startg事件\r\n self.stopInertiaMove = true;\r\n this.lastAngle = this.angle;\r\n this.wrap.addClass(\"ipu-noanimate\"); // 移除动画\r\n this.stopInertiaMove = true; // 停止自动减速滚动\r\n\r\n } else if (ev.type == 'panmove') {\r\n var moveAngle = this.calcAngle(ev.deltaY);\r\n var newAngle = this.lastAngle - moveAngle; //最新的角度\r\n //console.log('=='+newAngle);\r\n // 一个可以转动的最小值和最大值过滤\r\n if (newAngle < this.beginExceed) {\r\n newAngle = this.beginExceed;\r\n }\r\n if (newAngle > this.endExceed) {\r\n newAngle = this.endExceed;\r\n }\r\n this.setAngle(newAngle);\r\n\r\n } else { // end or cancel事件\r\n // console.log('end or cancel:' + ev.type);\r\n var v = ev.overallVelocityY; // 滑动的速度\r\n var dir = v > 0 ? -1 : 1; //加速度方向\r\n var deceleration = dir * 0.0006 * -1;\r\n var duration = Math.abs(v / deceleration); // 速度消减至0所需时间\r\n var dist = v * duration / 2; //最终移动多少\r\n\r\n var startAngle = this.angle;\r\n var distAngle = -this.calcAngle(dist);\r\n // console.log(\"dist=\" + dist + \", distAngle\" + distAngle);\r\n\r\n //----\r\n var srcDistAngle = distAngle;\r\n if (startAngle + distAngle < this.beginExceed) {\r\n distAngle = this.beginExceed - startAngle;\r\n duration = duration * (distAngle / srcDistAngle) * 0.6;\r\n }\r\n if (startAngle + distAngle > this.endExceed) {\r\n distAngle = this.endExceed - startAngle;\r\n duration = duration * (distAngle / srcDistAngle) * 0.6;\r\n }\r\n\r\n if (distAngle == 0) {\r\n this.endScroll();\r\n return;\r\n }\r\n this.scrollDistAngle(startAngle, distAngle, duration);\r\n }\r\n };\r\n\r\n // 计算移动的角度,转动的角度,就是移动的距离对应相关圆周\r\n // 2*r*PI = 360, angle = 360*c/(2*r*PI)\r\n var ca = 360 / (2 * r * Math.PI);\r\n Picker.prototype.calcAngle = function (c) {\r\n return c * ca;\r\n };\r\n\r\n /**\r\n * 为组件设置新的滚动角度\r\n *\r\n * @param {Number} newAngle 新的滚动角度\r\n * @param {Boolean} endScroll 是否为最终滚动角度,为最终滚动角度时,若索引更新可以触发onChange的回调\r\n */\r\n Picker.prototype.setAngle = function (newAngle, endScroll) {\r\n this.angle = newAngle; // 存储最新值\r\n this.wrap.css(\"transform\", \"perspective(\" + toRem(1000) + \"rem) rotateY(0deg) rotateX(\" + newAngle + \"deg)\");\r\n this.calcItemVisable(newAngle);\r\n\r\n if (endScroll) {\r\n var index = newAngle / itemAngle;\r\n var oldIndex = this.index;\r\n this.index = this.empty ? null : index; // 这里可以做一个判断,如果是empty,则index值可以不改变\r\n\r\n // 这个地方要判断下,数据更新或索引更新都要触发\r\n if (oldIndex != index || this.newData) {\r\n if (this.option.onChange && this.listen) {\r\n this.option.onChange(this.getSelectedItem(), this.index, oldIndex, this.newData);\r\n }\r\n this.newData = false;\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * 计算各子项滚动角度与新的滚动角度的值差异来决定显示的情况\r\n * 角度大于 90-(itemAngle/2)时,隐藏\r\n * 角度小于itemAngle/2表示最中心的项,显示并高亮\r\n * 其它值则表示此项为显示\r\n *\r\n * @param {Number} angle 新的滚动角度\r\n */\r\n Picker.prototype.calcItemVisable = function (angle) {\r\n this.items.each(function (index) {\r\n var difference = Math.abs(index * itemAngle - angle);\r\n\r\n if (difference < itemAngle / 2) {\r\n $(this).addClass(\"ipu-highlight ipu-visible\");\r\n } else if (difference >= (90 - itemAngle / 2)) { // 距离不能超过90度\r\n $(this).removeClass(\"ipu-highlight ipu-visible\");\r\n } else {\r\n $(this).addClass(\"ipu-visible\").removeClass(\"ipu-highlight\");\r\n }\r\n });\r\n };\r\n\r\n // 设置最后回归位置\r\n Picker.prototype.endScroll = function () {\r\n this.wrap.removeClass(\"ipu-noanimate\");\r\n var endAngle;\r\n\r\n if (this.angle < this.beginAngle) {\r\n endAngle = this.beginAngle;\r\n } else if (this.angle > this.endAngle) {\r\n endAngle = this.endAngle;\r\n } else {\r\n var index = parseInt((this.angle / itemAngle).toFixed(0));\r\n endAngle = (itemAngle * index);\r\n }\r\n\r\n this.setAngle(endAngle, true);\r\n };\r\n\r\n // 进行惯性滚动\r\n Picker.prototype.scrollDistAngle = function (startAngle, distAngle, duration) {\r\n var self = this;\r\n var nowTime = new Date().getTime();\r\n this.stopInertiaMove = false;\r\n duration = 1 * duration; // 滚动时长控制修改\r\n\r\n // hammer调用的惯性函数\r\n (function (nowTime, startAngle, distAngle, duration) {\r\n var frameInterval = 13;\r\n var stepCount = duration / frameInterval;\r\n var stepIndex = 0;\r\n\r\n (function inertiaMove() {\r\n if (self.stopInertiaMove) return;\r\n var newAngle = self.quartEaseOut(stepIndex, startAngle, distAngle, stepCount);\r\n self.setAngle(newAngle);\r\n stepIndex++;\r\n\r\n if (stepIndex > stepCount - 1 || newAngle < self.beginExceed || newAngle > self.endExceed) {\r\n self.endScroll();\r\n return;\r\n }\r\n\r\n setTimeout(inertiaMove, frameInterval);\r\n })();\r\n\r\n })(nowTime, startAngle, distAngle, duration);\r\n };\r\n\r\n /**\r\n * 设置是否监听触发onChange回调\r\n *\r\n * @param {Boolean} listen\r\n */\r\n Picker.prototype.setListen = function (listen) {\r\n this.listen = !!listen;\r\n };\r\n\r\n Picker.prototype.quartEaseOut = function (t, b, c, d) {\r\n return -c * ((t = t / d - 1) * t * t * t - 1) + b;\r\n };\r\n\r\n /**\r\n * 设置选中项,若子项的value属性为value,则设置该项为选中项\r\n *\r\n * @param value\r\n */\r\n Picker.prototype.setSelectedValue = function (value) {\r\n var self = this;\r\n for (var index in self.data) {\r\n var item = self.data[index];\r\n if (item.value == value) {\r\n self.setAngle(index * itemAngle, true);\r\n return;\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * 获取选中的子项,若子项集为空时,返回空对象\r\n *\r\n * @returns {Object}\r\n */\r\n Picker.prototype.getSelectedItem = function () {\r\n return this.empty ? {} : this.data[this.index];\r\n };\r\n\r\n /**\r\n * 获取选中的子项的value属性\r\n * @returns\r\n */\r\n Picker.prototype.getSelectedValue = function () {\r\n return this.getSelectedItem().value;\r\n };\r\n\r\n /**\r\n * 返回选中项的text属性\r\n * @return {String}\r\n */\r\n Picker.prototype.getSelectedText = function () {\r\n return this.getSelectedItem().text;\r\n };\r\n\r\n /**\r\n * 获取选中项的索引,若子项集为空则返回null\r\n * @returns {Number}\r\n */\r\n Picker.prototype.getSelectedIndex = function () {\r\n return this.index;\r\n };\r\n\r\n ipu.Picker = Picker;\r\n\r\n})(ipu || window, jQuery, Hammer);\r\n\n// popPicker\r\n(function (ipu, $) {\r\n var Picker = ipu.Picker;\r\n\r\n /**\r\n * @class\r\n * 原生select的替代实现,适应数据较多或级联的情况\r\n *\r\n * @example\r\n // 配置项data的数据结构\r\n var data = [{text:'显示名称', value:''}...];\r\n\r\n // layer=1的数据结构\r\n var data-1 = [{text:'湖南', value:'HN'}, {text:'湖北', value:'HB'}];\r\n\r\n // layer=2时的数据结构,有额外data属性存放下一层级数据\r\n var data-1 = [{\r\n text:'湖南',value:'HN', data:[{text:'长沙', value:'CS'}, {text:'湘谭', value:'XT'}]\r\n },{\r\n text:'湖北',value:'HB', data:[{text:'武汉', value:'WH'}, {text:'天门', value:'TM'}]\r\n }\r\n ];\r\n\r\n *\r\n * @constructor 不能直接访问该类,调用{@link ipu#navBar ipu.popPicker(slt, option)}生成实例\r\n * @param {String|jqueryObj} slt\r\n * jquery选择器字符串或jquery对象,用来查找要被组件初始化化的dom\r\n * @param {Object} option 组件配置参数,默认配置见 {@link #cfg-defaultOption}\r\n */\r\n function PopPicker(option) {\r\n this.option = $.extend({}, this.defaultOption, option);\r\n if (!Picker) {\r\n Picker = ipu.Picker;\r\n }\r\n this._init();\r\n }\r\n\r\n PopPicker.prototype._init = function () {\r\n this.holder = $(this.option.template).appendTo(\"body\");\r\n var bodyHtml = $(\".ipu-poppicker-body\", this.holder);\r\n\r\n var layer = this.option.layer;\r\n var width = (100 / layer) + \"%\";\r\n this.pickers = new Array(layer);\r\n var self = this;\r\n var pickerHtml;\r\n this.mask = this.createMask();\r\n\r\n // 先初始化最底层picerk,再上面来\r\n for (var i = layer - 1; i >= 0; i--) {\r\n pickerHtml = $(this.option.pickerTemplate).prependTo(bodyHtml).css({width: width});\r\n\r\n this.pickers[i] = new Picker(pickerHtml, {\r\n onChange: (function (i) {\r\n return function (item) { // 更新底部的值\r\n if (i != layer - 1) {\r\n self.pickers[i + 1].setItems(item.data);\r\n }\r\n };\r\n })(i)\r\n });\r\n }\r\n\r\n $(\".ipu-poppicker-btn-ok\", this.holder).click(function () {\r\n var rs = self.getSelectItems();\r\n if (self.option.callBack(rs) !== false) {\r\n self.hide();\r\n }\r\n }).text(this.option.btns[1]);\r\n\r\n $(\".ipu-poppicker-btn-cancel\", this.holder).click(function () {\r\n self.hide();\r\n }).text(this.option.btns[0]);\r\n };\r\n\r\n /**\r\n * 组件默认配置项\r\n *\r\n * @cfg {Object} defaultOption\r\n * @cfg {String} defaultOption.template html结构\r\n * @cfg {String} defaultOption.pickerTemplate 内容dom选择器\r\n * @cfg {Object[]} defaultOption.data 选择项数据\r\n * @cfg {String} defaultOption.data.text 子项展示文本\r\n * @cfg {*} defaultOption.data.value 子项值\r\n * @cfg {Object[]} defaultOption.data.data 有更多层级时,此属性存放下一层级的数据\r\n * @cfg {Number} defaultOption.layer=1 数据层数\r\n * @cfg {String[]} defaultOption.btns=['取消', '确认'] 按钮文本\r\n * @cfg {Function} defaultOption.callBack=null 回调函数\r\n */\r\n PopPicker.prototype.defaultOption = {\r\n template: '<div class=\"ipu-poppicker\">'\r\n + '<div class=\"ipu-poppicker-header\">'\r\n + '<button class=\"ipu-btn ipu-btn-s ipu-poppicker-btn-cancel\">取消</button>'\r\n + '<button class=\"ipu-btn ipu-btn-s ipu-poppicker-btn-ok\">确定</button>'\r\n + '</div>'\r\n + '<div class=\"ipu-poppicker-body\">'\r\n + '</div>'\r\n + '</div>',\r\n pickerTemplate: '<div class=\"ipu-picker\">'\r\n + '<div class=\"ipu-picker-selectbox\"></div>'\r\n + '<ul></ul>'\r\n + '</div>',\r\n data: [], // 数据\r\n layer: 1, // 数据层级\r\n btns: ['取消', '确认'],\r\n callBack: function () { // 选择数据时的回调函数\r\n\r\n }\r\n };\r\n\r\n /**\r\n * 设置选择项数据\r\n *\r\n * @param{[Object]} data 选择项数组\r\n * @param {String} data.text 每个选择项的文本\r\n * @param {[Object]} data.data 如果有多层选择的话,应该有一个data属性\r\n */\r\n PopPicker.prototype.setData = function (data) {\r\n this.pickers[0].setItems(data);\r\n };\r\n\r\n /**\r\n * 显示选择器\r\n *\r\n * @param callBack\r\n */\r\n PopPicker.prototype.show = function (callBack) {\r\n if (callBack) {\r\n this.option.callBack = callBack;\r\n }\r\n this.mask.show();\r\n this.holder.addClass(\"ipu-current\");\r\n };\r\n\r\n /**\r\n * 隐藏选择器\r\n */\r\n PopPicker.prototype.hide = function () {\r\n this.mask.close();\r\n this.holder.removeClass(\"ipu-current\");\r\n };\r\n\r\n /**\r\n * 获取用户选择的项,如果配置项layer为1,则直接返回选择项,\r\n * 否则返回一个数组返回每层选中的项\r\n *\r\n */\r\n PopPicker.prototype.getSelectItems = function () {\r\n if (this.option.layer == 1) {\r\n return this.pickers[0].getSelectedItem();\r\n } else {\r\n var rs = [];\r\n for (var i = 0; i < this.option.layer; i++) {\r\n rs.push(this.pickers[i].getSelectedItem());\r\n }\r\n return rs;\r\n }\r\n };\r\n\r\n // 应该移除callback参数,提取出业成一个工具方法\r\n PopPicker.prototype.createMask = function (callback) {\r\n var self = this;\r\n var element = document.createElement('div');\r\n element.classList.add(\"ipu-picker-backup\");\r\n //element.addEventListener($.EVENT_MOVE, $.preventDefault);\r\n element.addEventListener('click', function () {\r\n self.hide();\r\n });\r\n var mask = [element];\r\n mask._show = false;\r\n mask.show = function () {\r\n mask._show = true;\r\n element.setAttribute('style', 'opacity:1');\r\n document.body.appendChild(element);\r\n return mask;\r\n };\r\n mask._remove = function () {\r\n if (mask._show) {\r\n mask._show = false;\r\n element.setAttribute('style', 'opacity:0');\r\n setTimeout(function () {\r\n var body = document.body;\r\n element.parentNode === body && body.removeChild(element);\r\n }, 350);\r\n }\r\n return mask;\r\n };\r\n mask.close = function () {\r\n if (mask._show) {\r\n if (callback) {\r\n if (callback() !== false) {\r\n mask._remove();\r\n }\r\n } else {\r\n mask._remove();\r\n }\r\n }\r\n };\r\n return mask;\r\n };\r\n\r\n /**\r\n * @member ipu\r\n * 生成PopPicker实例,参数信息见{@link PopPicker#method-constructor}\r\n *\r\n * @param {String} slt\r\n * @param {Object} option\r\n * @returns {PopPicker}\r\n */\r\n ipu.popPicker = function (option) {\r\n return new PopPicker(option);\r\n };\r\n\r\n})(ipu || window, jQuery);\r\n\n(function (ipu, $) {\r\n\r\n /**\r\n * @class\r\n * 进度条\r\n *\r\n * @example\r\n * <!-- 组件html -->\r\n * <div class=\"ipu-ipu-progress \">\r\n * <span class=\"ipu-progressbar\"></span>\r\n * </div>\r\n *\r\n *\r\n * @constructor 不能直接访问该类,调用 {@link ipu#progressBar}生成实例\r\n * @param {String|jqueryObj} slt\r\n * jquery选择器字符串或jquery对象,用来查找要被组件初始化化的dom\r\n * @param {Object} option 组件配置参数,默认配置见 {@link #cfg-defaultOption}\r\n */\r\n function ProgressBar(id, option) {\r\n this.id = id;\r\n this.level = option.level;\r\n this.progress = option.progress;\r\n this.progressBar = $(id).eq(0);\r\n\r\n if (option.progress != null) {\r\n this.setProgress(this.progress);\r\n }\r\n if (option.level != null) {\r\n this.setLevel(this.level);\r\n }\r\n }\r\n\r\n /**\r\n * @cfg defaultOption 刷新组件默认配置\r\n * @cfg {default|warning|highlight|success} defaultOption.level='default' 级别,显示颜色\r\n * @cfg {Number} defaultOption.progress=null 当前进度百分比\r\n *\r\n */\r\n\r\n /**\r\n * 设置百分进度\r\n *\r\n * @param {Number} pro\r\n */\r\n ProgressBar.prototype.setProgress = function (pro) {\r\n if (pro < 0 || pro > 100) return;\r\n\r\n $(this.progressBar.find(\".ipu-progressbar\")).css(\"transform\", \"translate3d(\" + (-(100 - pro)) + \"%, 0px, 0px)\");\r\n this.progress = pro;\r\n };\r\n\r\n /**\r\n * 获取百分进度\r\n *\r\n * @returns {Number|*}\r\n */\r\n ProgressBar.prototype.getProgress = function () {\r\n return this.progress;\r\n };\r\n\r\n /**\r\n * 设置进度条级别\r\n *\r\n * @param {default | success | highlight | warning} level\r\n */\r\n ProgressBar.prototype.setLevel = function (level) {\r\n if (level == \"default\") {\r\n $(this.progressBar).removeClass(\"ipu-progressbar-success ipu-progressbar-hightlight ipu-progressbar-warning\");\r\n $(this.progressBar).addClass(\"ipu-progress\");\r\n } else if (level == \"success\") {\r\n $(this.progressBar).removeClass(\"ipu-progressbar-highlight ipu-progressbar-warning\");\r\n $(this.progressBar).addClass(\"ipu-progressbar-success\");\r\n } else if (level == \"highlight\") {\r\n $(this.progressBar).removeClass(\"ipu-progressbar-success ipu-progressbar-warning\");\r\n $(this.progressBar).addClass(\"ipu-progressbar-highlight\");\r\n } else if (level == \"warning\") {\r\n $(this.progressBar).removeClass(\"ipu-progressbar-success ipu-progressbar-highlight\");\r\n $(this.progressBar).addClass(\"ipu-progressbar-warning\");\r\n }\r\n };\r\n\r\n /**\r\n * @member ipu\r\n * 生成PopPicker实例,参数信息见{@link ProgressBar#method-constructor}\r\n *\r\n * @param {String} slt\r\n * @param {Object} option\r\n * @returns {ProgressBar}\r\n */\r\n ipu.progressBar = function (slt, option) {\r\n return new ProgressBar(slt, option);\r\n };\r\n})(ipu || window, jQuery);\r\n\n// 设置上下条件长度,或计算函数\n// 处理resize的问题,用户主动调用refresh??\n// 底部启用或停用时,应该刷新组件iscroll高度\n// 顶部正在加载时,自动停止底端加载状态,停用底部加载,停用底部加载时,可以不隐藏,变性成显示不见,或者隐藏,然后修改iscroll参数\n\n(function (ipu, $, iScroll) {\n /**\n * @class\n * 通过IScroll.js实现上拉下拉加载\n *\n * @example\n * <!-- 组件html结构,最外层div应有一个固定的高度,会在此元素上初始化iScroll -->\n * <div>\n * <div class=\"ipu-refresh-wrapper\">\n * <!-- 此处组件初始化后,会添加上拉html -->\n * <div class=\"refresh-content\">\n * 内容区...\n * </div>\n * <!-- 此处组件初始化后,会添加下拉html -->\n * </div>\n * </div>\n *\n * @uses IScroll.js\n *\n * @constructor 不能直接访问该类,调用ipu.refresh(slt, option)生成实例\n * @param {String|JqueryObj|Dom} slt\n * jquery选择器字符串或jquery对象,用来查找要被组件初始化化的dom\n * @param {Object} option\n * 组件参数\n */\n function Refresh(slt, option) {\n this.option = $.extend({}, this.defaultOption, option);\n this.el = $(slt).get(0);\n this._initBottomAndTop();\n var me = this;\n\n this.iScrollOption = {\n vScrollbar: false, // 不显示滚动条\n onScrollMove: function (e) {\n if (me.topEnable && !me.topLoading) { // 顶部是松手才加载\n if (this.y >= me.topPullOffset && !me.topEl.hasClass('ipu-refresh-toload')) { // 达到刷新距离,更新显示状态\n me.topEl.addClass('ipu-refresh-toload');\n } else if (this.y < me.topPullOffset && me.topEl.hasClass('ipu-refresh-toload')) { // 从达到刷新距离更新为未达到距离,更新显示状态\n me.topEl.removeClass('ipu-refresh-toload');\n }\n }\n\n me._checkBottomLoading(); // 底部加载条件和顶部条件不一样,只要滚动离底部一定高度就开始加载\n me.goTop = this.y > me.topPullOffset; // 记录是否位于顶部位置,以便刷新后可以回到此位置\n },\n onBeforeScrollEnd: function () { // 一定是用户拖动触发,在滚动结束前应该触发\n me._checkTopLoading();\n me._checkBottomLoading();\n },\n onScrollEnd: function () { // 这个事件可能由非用户拖动时触发,可能是拖动惯性导致,所有顶部不应该处理,但顶部不管是否惯性,位置条件满足即触发\n if (me.topLoading && this.y < this.minScrollY && me.goTop) {\n me.iScroll.scrollTo(0, this.minScrollY, 0);\n }\n me._checkBottomLoading(); // 在beforend执行还不够,还在要end执行\n },\n onRefresh: function () { // 刷新时,若顶部加载还在进行,且当前显示的顶部加载,则继续显示,否则刷新后会消失顶部加载,这里代码没有考虑重用了,应该可以做一步提取\n if (me.topLoading) { // 如果顶部在加载,则刷新的时候,设置最小顶部距离,显示顶部加载状态\n this.minScrollY = this.minScrollY + me.topPullOffset;\n }\n }\n };\n\n this.iScrollOption = $.extend({}, this.option.iScrollOption, this.iScrollOption);\n this.iScroll = new iScroll(this.el, this.iScrollOption);\n this._checkContentLoading();\n }\n\n /**\n * @cfg defaultOption 刷新组件默认配置\n * @cfg {Function} defaultOption.bottomLoadFun=null 上拉时,触发底加载的响应函数\n * @cfg {Function} defaultOption.topLoadFun=null 下拉时,触发顶部加载的响应函数\n * @cfg {Boolean} defaultOption.initEnableTop=true 初始化时,是否启用顶部加载功能\n * @cfg {Boolean} defaultOption.initEnableBottom=true 初始化时,是否启用底部加载功能\n * @cfg {String} defaultOption.bottomLoadHtml=... 底部加载时显示的html片段,不建议变动\n * @cfg {String} defaultOption.topLoadHtml=... 顶部加载时显示的html片段,不建议变动\n * @cfg {Number} defaultOption.bottomAddLen=0 距离底部多远时,触发底部加载\n *\n */\n Refresh.prototype.defaultOption = {\n bottomLoadFun: null, // 底部加载处理函数\n topLoadFun: null, // 顶部加载处理函数\n initEnableTop: true, // 初始时启用刷新,有时用户并不想启用\n initEnableBottom: true, // 初始时启用加载更多,用时用户并不想启用\n bottomLoadHtml: '<div class=\"ipu-refresh-bottom\"><span class=\"ipu-refresh-loading\"></span></div>', // 默认底部加载显示内容\n topLoadHtml: '<div class=\"ipu-refresh-top\"><span class=\"ipu-refresh-loading\"></span><div class=\"ipu-refresh-arrow\"></div></div>',\n // 默认顶部加载显示内容,最上层节点class有下面三个阶段变化\n // 默认阶段,不是顶部加载状态时,且拖动时未达到加载距离,无特殊class,移除ipu-refresh-top-loading\n // 拖动达到加载距离,则增加class:ipu-refresh-toload\n // 加载中,则增加class:ipu-refresh-top-loading,移除class:ipu-refresh-toload\n bottomAddLen: 0, // 底部提前加载距离,单位px\n iScrollOption: {} // 主要是用来接收外面一些函数,不能传递回调的相关函数如refresh,也可在本地函数调用完后,再调用参数的函数,不推荐\n };\n\n Refresh.prototype._initBottomAndTop = function () {\n this.scrollEl = $(\">.ipu-refresh-wrapper\", this.el);\n this.bottomEl = $(this.option.bottomLoadHtml).appendTo(this.scrollEl);\n this.topEl = $(this.option.topLoadHtml).prependTo(this.scrollEl);\n\n this.topPullOffset = this.topEl.outerHeight();\n this.bottomPullOffset = this.bottomEl.outerHeight() + this.option.bottomAddLen; // 增加100;最好配一个额外参数\n\n /** @property {Boolean} 顶部是否加载中 */\n this.topLoading = false; // 顶部正在载加载\n\n /** @property {Boolean} 底部是否加载中 */\n this.bottomLoading = false; // 底部正在加载\n\n /** @property {Boolean} 底部是否可加载 */\n this.bottomEnable = this.option.initEnableBottom && !!this.option.bottomLoadFun;\n\n /** @property {Boolean} 顶部是否可加载 */\n this.topEnable = this.option.initEnableTop && !!this.option.topLoadFun;\n\n this.goTop = false; // 用来处理,因为iScroll使用momentum(惯性), 导致有时顶部显示不正确问题,true表示顶部显示加载条\n\n this.enableBottom(this.bottomEnable);\n this.enableTop(this.topEnable);\n };\n\n // 检查是否需要底部加载\n Refresh.prototype._checkBottomLoading = function () {\n if (this.bottomEnable) {\n if (this.iScroll.y < this.iScroll.maxScrollY + this.bottomPullOffset) {\n this._startBottomLoading();\n }\n }\n };\n\n Refresh.prototype._checkTopLoading = function () {\n if (this.topEnable) {\n if (this.topEl.hasClass('ipu-refresh-toload')) {\n this._startTopLoading();\n }\n }\n };\n\n // 检查内容是否超出容器高度,未超出时,自动调用底部加载\n Refresh.prototype._checkContentLoading = function () {\n if (this.bottomEnable) {\n if (this.iScroll.maxScrollY >= -this.bottomPullOffset) { // 此处要计算底端的高度\n this._startBottomLoading();\n }\n }\n };\n\n // 开始底部加载\n Refresh.prototype._startBottomLoading = function () {\n if (!this.bottomLoading) {\n this.bottomLoading = true;\n this.option.bottomLoadFun(); // 刷新当前索引加载更多的数据\n }\n };\n\n // 开始顶部加载\n Refresh.prototype._startTopLoading = function () {\n if (!this.topLoading) {\n this.topLoading = true;\n this.topEl.removeClass('ipu-refresh-toload').addClass('ipu-refresh-top-loading');\n this.iScroll.minScrollY = this.iScroll.minScrollY + this.topPullOffset;\n this.option.topLoadFun(); // 刷新当前索引加载更多的数据\n }\n };\n\n /**\n * 结束底部加载,defaultOption.bottomLoadFun中处理完加载后,最后调用此方法\n */\n Refresh.prototype.endBottomLoading = function () {\n this.bottomLoading = false;\n this.refresh();\n };\n\n /**\n * 结束顶部加载,defaultOption.topLoadFun中处理完加载后,最后调用此方法\n */\n Refresh.prototype.endTopLoading = function () {\n this.topEl.removeClass('ipu-refresh-top-loading');\n this.topLoading = false;\n // this.iScroll.scrollTo(0, 0); // 刷新加载则应该回到顶部,待测试确认\n this.refresh();\n };\n\n /**\n * 是否启动顶部加载功能\n *\n * @param {Boolean} enable\n */\n Refresh.prototype.enableTop = function (enable) {\n this.topEnable = enable;\n if (enable) {\n this.topEl.show();\n } else {\n this.topEl.hide();\n }\n };\n\n /**\n * 是否启用底部加载功能\n *\n * @param {Boolean} enable\n */\n Refresh.prototype.enableBottom = function (enable) {\n this.bottomEnable = enable;\n if (enable) {\n this.bottomEl.show();\n } else {\n this.bottomEl.hide();\n }\n };\n\n /**\n * 在内容发生变化时,但是又不是因为顶部加载或底部加载导致的,此时调用此方法刷新IScroll\n */\n Refresh.prototype.refresh = function () {\n this.iScroll.refresh();\n this._checkContentLoading();\n };\n\n\n /**\n * @member ipu\n * 生成PopPicker实例,参数信息见{@link Refresh#method-constructor}\n *\n * @param {String} slt\n * @param {Object} option\n * @returns {Refresh}\n */\n ipu.refresh = function (slt, optoins) {\n return new Refresh(slt, optoins);\n };\n\n})(ipu || window, jQuery, iScroll);\n\n// Tab\r\n(function (ipu, $) {\r\n\r\n /**\r\n * @class\r\n * tab切换组件功能实现\r\n *\r\n * @example\r\n * <!-- html结构 -->\r\n * <div class=\"ipu-tab\"> <!-- 如果class中添加 ipu-tab-fixed,则可固定头部,此时需要父元素的高度是确定的 -->\r\n * <ul class=\"ipu-tab-title ipu-tab-title-link\"> <!-- 页头有 ipu-tab-title-link 和 ipu-tab-title-button两种样式 -->\r\n * <li>热门推荐</li>\r\n * <li class=\"ipu-current\">全部表情</li> <!-- class为ipu-current为默认选中项 -->\r\n * <li>表情</li>\r\n * <li>表情</li>\r\n * </ul>\r\n * <div class=\"ipu-tab-body\">\r\n * <ul class=\"ipu-tab-body-wrapper\">\r\n * <li>自定义内容</li>\r\n * <li class=\"\">选项2内容</li>\r\n * <li class=\"\">选项3内容</li>\r\n * <li class=\"\">选项4内容</li>\r\n * </ul>\r\n * </div>\r\n * </div>\r\n *\r\n *\r\n * @constructor 不能直接访问该类,调用ipu.tab(slt, option)生成实例\r\n * @param {string|jqueryObj} slt\r\n * jquery选择器字符串或jquery对象,用来查找要被组件初始化化的dom\r\n * @param {object} option\r\n * 组件参数\r\n */\r\n function Tab(slt, option) {\r\n this.el = $(slt).get(0);\r\n this.titleItems = $(\".ipu-tab-title:first>li\", this.el);\r\n this.bodyWrapper = $(\".ipu-tab-body-wrapper:first\", this.el);\r\n this.contentItems = $(\">li\", this.bodyWrapper);\r\n\r\n this.option = $.extend({}, this.defaultOption, option);\r\n this.itemSize = this.contentItems.size();\r\n this.fixed = $(this.el).is(\".ipu-tab-fixed\"); // 是否为固定高度的\r\n\r\n var that = this;\r\n this.titleItems.each(function (index) {\r\n $(this).click(function () {\r\n that.show(index);\r\n });\r\n });\r\n\r\n var index = this.titleItems.filter(\".ipu-current\").index();\r\n if (index == -1) {\r\n index = 0;\r\n }\r\n\r\n this.show(index);\r\n }\r\n\r\n /**\r\n * 默认配置项\r\n * @cfg defaultOption = { callBack: function (index) {}};\r\n * @cfg defaultOption.callBack 切换tab项时的回调函数,参数为显示的项索引\r\n */\r\n Tab.prototype.defaultOption = {\r\n callBack: function (index) {\r\n }\r\n };\r\n\r\n /**\r\n * 显示第几项内容\r\n * @param {number} index 要显示的项索引\r\n */\r\n Tab.prototype.show = function (index) {\r\n if (this.fixed) {\r\n var move = -index * 100 + \"%\";\r\n this.bodyWrapper.css(\"transform\", \"translate3d(\" + move + \", 0, 0)\");\r\n }\r\n this.contentItems.eq(index).addClass(\"ipu-current\").siblings().removeClass(\"ipu-current\");\r\n this.titleItems.eq(index).addClass(\"ipu-current\").siblings().removeClass(\"ipu-current\");\r\n this._end(index);\r\n };\r\n\r\n Tab.prototype._end = function (index) {\r\n this.lastIndex = this.currentIndex;\r\n this.currentIndex = index;\r\n\r\n if (this.option.callBack) {\r\n this.option.callBack(index, this.lastIndex);\r\n }\r\n };\r\n\r\n ipu.tab = function (slt, option) {\r\n return new Tab(slt, option);\r\n };\r\n})(ipu || window, jQuery);\r\n\r\n\n\r\n // 初始化代码\r\n jQuery(function () {\r\n // 添加一个touchstart空函数,让:active样式可以在ios上生效\r\n // 新版默认不需要事件好像也可生效\r\n jQuery(\"body\").on(\"touchstart\",function (e) {});\r\n\r\n // 处理ios点击延迟问题\r\n FastClick.attach(document.body);\r\n });\r\n\r\n return ipu;\r\n }\r\n\r\n // todo:可以添加一个和其它库的适配处理,\r\n // 这里假设第三方库,jquery,iScroll,Hammer的史称已经固定\r\n if ( typeof define === \"function\" && define.amd ) {\r\n define(['jquery', 'iScroll', 'Hammer', 'FastClick'], function (jQuery, iScroll, Hammer, FastClick) {\r\n return window.ipu = setup(jQuery, iScroll, Hammer, FastClick);\r\n });\r\n } else {\r\n window.ipu = setup(window.jQuery, window.iScroll, window.Hammer, window.FastClick);\r\n }\r\n})();\r\n\r\n//# sourceMappingURL=ipu.js.map\r\n"]}
|