lipengtao 8 years ago
parent
commit
32effc82f7
1 changed files with 1022 additions and 0 deletions
  1. 1022 0
      app/js/public/mui.picker.all.js

+ 1022 - 0
app/js/public/mui.picker.all.js

1
/**
2
 * 选择列表插件
3
 * varstion 2.0.0
4
 * by Houfeng
5
 * Houfeng@DCloud.io
6
 */
7
8
(function($, window, document, undefined) {
9
10
	var MAX_EXCEED = 30;
11
	var VISIBLE_RANGE = 90;
12
	var DEFAULT_ITEM_HEIGHT = 40;
13
	var BLUR_WIDTH = 10;
14
15
	var rad2deg = $.rad2deg = function(rad) {
16
		return rad / (Math.PI / 180);
17
	};
18
19
	var deg2rad = $.deg2rad = function(deg) {
20
		return deg * (Math.PI / 180);
21
	};
22
23
	var platform = navigator.platform.toLowerCase();
24
	var userAgent = navigator.userAgent.toLowerCase();
25
	var isIos = (userAgent.indexOf('iphone') > -1 ||
26
			userAgent.indexOf('ipad') > -1 ||
27
			userAgent.indexOf('ipod') > -1) &&
28
		(platform.indexOf('iphone') > -1 ||
29
			platform.indexOf('ipad') > -1 ||
30
			platform.indexOf('ipod') > -1);
31
	//alert(isIos);
32
33
	var Picker = $.Picker = function(holder, options) {
34
		var self = this;
35
		self.holder = holder;
36
		self.options = options || {};
37
		self.init();
38
		self.initInertiaParams();
39
		self.calcElementItemPostion(true);
40
		self.bindEvent();
41
	};
42
43
	Picker.prototype.findElementItems = function() {
44
		var self = this;
45
		self.elementItems = [].slice.call(self.holder.querySelectorAll('li'));
46
		return self.elementItems;
47
	};
48
49
	Picker.prototype.init = function() {
50
		var self = this;
51
		self.list = self.holder.querySelector('ul');
52
		self.findElementItems();
53
		self.height = self.holder.offsetHeight;
54
		self.r = self.height / 2 - BLUR_WIDTH;
55
		self.d = self.r * 2;
56
		self.itemHeight = self.elementItems.length > 0 ? self.elementItems[0].offsetHeight : DEFAULT_ITEM_HEIGHT;
57
		self.itemAngle = parseInt(self.calcAngle(self.itemHeight * 0.8));
58
		self.hightlightRange = self.itemAngle / 2;
59
		self.visibleRange = VISIBLE_RANGE;
60
		self.beginAngle = 0;
61
		self.beginExceed = self.beginAngle - MAX_EXCEED;
62
		self.list.angle = self.beginAngle;
63
		if (isIos) {
64
			self.list.style.webkitTransformOrigin = "center center " + self.r + "px";
65
		}
66
	};
67
68
	Picker.prototype.calcElementItemPostion = function(andGenerateItms) {
69
		var self = this;
70
		if (andGenerateItms) {
71
			self.items = [];
72
		}
73
		self.elementItems.forEach(function(item) {
74
			var index = self.elementItems.indexOf(item);
75
			self.endAngle = self.itemAngle * index;
76
			item.angle = self.endAngle;
77
			item.style.webkitTransformOrigin = "center center -" + self.r + "px";
78
			item.style.webkitTransform = "translateZ(" + self.r + "px) rotateX(" + (-self.endAngle) + "deg)";
79
			if (andGenerateItms) {
80
				var dataItem = {};
81
				dataItem.text = item.innerHTML || '';
82
				dataItem.value = item.getAttribute('data-value') || dataItem.text;
83
				self.items.push(dataItem);
84
			}
85
		});
86
		self.endExceed = self.endAngle + MAX_EXCEED;
87
		self.calcElementItemVisibility(self.beginAngle);
88
	};
89
90
	Picker.prototype.calcAngle = function(c) {
91
		var self = this;
92
		var a = b = parseFloat(self.r);
93
		//直径的整倍数部分直接乘以 180
94
		c = Math.abs(c); //只算角度不关心正否值
95
		var intDeg = parseInt(c / self.d) * 180;
96
		c = c % self.d;
97
		//余弦
98
		var cosC = (a * a + b * b - c * c) / (2 * a * b);
99
		var angleC = intDeg + rad2deg(Math.acos(cosC));
100
		return angleC;
101
	};
102
103
	Picker.prototype.calcElementItemVisibility = function(angle) {
104
		var self = this;
105
		self.elementItems.forEach(function(item) {
106
			var difference = Math.abs(item.angle - angle);
107
			if (difference < self.hightlightRange) {
108
				item.classList.add('highlight');
109
			} else if (difference < self.visibleRange) {
110
				item.classList.add('visible');
111
				item.classList.remove('highlight');
112
			} else {
113
				item.classList.remove('highlight');
114
				item.classList.remove('visible');
115
			}
116
		});
117
	};
118
119
	Picker.prototype.setAngle = function(angle) {
120
		var self = this;
121
		self.list.angle = angle;
122
		self.list.style.webkitTransform = "perspective(1000px) rotateY(0deg) rotateX(" + angle + "deg)";
123
		self.calcElementItemVisibility(angle);
124
	};
125
126
	Picker.prototype.bindEvent = function() {
127
		var self = this;
128
		var lastAngle = 0;
129
		var startY = null;
130
		var isPicking = false;
131
		self.holder.addEventListener($.EVENT_START, function(event) {
132
			isPicking = true;
133
			event.preventDefault();
134
			self.list.style.webkitTransition = '';
135
			startY = (event.changedTouches ? event.changedTouches[0] : event).pageY;
136
			lastAngle = self.list.angle;
137
			self.updateInertiaParams(event, true);
138
		}, false);
139
		self.holder.addEventListener($.EVENT_END, function(event) {
140
			isPicking = false;
141
			event.preventDefault();
142
			self.startInertiaScroll(event);
143
		}, false);
144
		self.holder.addEventListener($.EVENT_CANCEL, function(event) {
145
			isPicking = false;
146
			event.preventDefault();
147
			self.startInertiaScroll(event);
148
		}, false);
149
		self.holder.addEventListener($.EVENT_MOVE, function(event) {
150
			if (!isPicking) {
151
				return;
152
			}
153
			event.preventDefault();
154
			var endY = (event.changedTouches ? event.changedTouches[0] : event).pageY;
155
			var dragRange = endY - startY;
156
			var dragAngle = self.calcAngle(dragRange);
157
			var newAngle = dragRange > 0 ? lastAngle - dragAngle : lastAngle + dragAngle;
158
			if (newAngle > self.endExceed) {
159
				newAngle = self.endExceed
160
			}
161
			if (newAngle < self.beginExceed) {
162
				newAngle = self.beginExceed
163
			}
164
			self.setAngle(newAngle);
165
			self.updateInertiaParams(event);
166
		}, false);
167
		//--
168
		self.list.addEventListener('tap', function(event) {
169
			elementItem = event.target;
170
			if (elementItem.tagName == 'LI') {
171
				self.setSelectedIndex(self.elementItems.indexOf(elementItem), 200);
172
			}
173
		}, false);
174
	};
175
176
	Picker.prototype.initInertiaParams = function() {
177
		var self = this;
178
		self.lastMoveTime = 0;
179
		self.lastMoveStart = 0;
180
		self.stopInertiaMove = false;
181
	};
182
183
	Picker.prototype.updateInertiaParams = function(event, isStart) {
184
		var self = this;
185
		var point = event.changedTouches ? event.changedTouches[0] : event;
186
		if (isStart) {
187
			self.lastMoveStart = point.pageY;
188
			self.lastMoveTime = event.timeStamp || Date.now();
189
			self.startAngle = self.list.angle;
190
		} else {
191
			var nowTime = event.timeStamp || Date.now();
192
			if (nowTime - self.lastMoveTime > 300) {
193
				self.lastMoveTime = nowTime;
194
				self.lastMoveStart = point.pageY;
195
			}
196
		}
197
		self.stopInertiaMove = true;
198
	};
199
200
	Picker.prototype.startInertiaScroll = function(event) {
201
		var self = this;
202
		var point = event.changedTouches ? event.changedTouches[0] : event;
203
		/** 
204
		 * 缓动代码
205
		 */
206
		var nowTime = event.timeStamp || Date.now();
207
		var v = (point.pageY - self.lastMoveStart) / (nowTime - self.lastMoveTime); //最后一段时间手指划动速度  
208
		var dir = v > 0 ? -1 : 1; //加速度方向  
209
		var deceleration = dir * 0.0006 * -1;
210
		var duration = Math.abs(v / deceleration); // 速度消减至0所需时间  
211
		var dist = v * duration / 2; //最终移动多少 
212
		var startAngle = self.list.angle;
213
		var distAngle = self.calcAngle(dist) * dir;
214
		//----
215
		var srcDistAngle = distAngle;
216
		if (startAngle + distAngle < self.beginExceed) {
217
			distAngle = self.beginExceed - startAngle;
218
			duration = duration * (distAngle / srcDistAngle) * 0.6;
219
		}
220
		if (startAngle + distAngle > self.endExceed) {
221
			distAngle = self.endExceed - startAngle;
222
			duration = duration * (distAngle / srcDistAngle) * 0.6;
223
		}
224
		//----
225
		if (distAngle == 0) {
226
			self.endScroll();
227
			return;
228
		}
229
		self.scrollDistAngle(nowTime, startAngle, distAngle, duration);
230
	};
231
232
	Picker.prototype.scrollDistAngle = function(nowTime, startAngle, distAngle, duration) {
233
		var self = this;
234
		self.stopInertiaMove = false;
235
		(function(nowTime, startAngle, distAngle, duration) {
236
			var frameInterval = 13;
237
			var stepCount = duration / frameInterval;
238
			var stepIndex = 0;
239
			(function inertiaMove() {
240
				if (self.stopInertiaMove) return;
241
				var newAngle = self.quartEaseOut(stepIndex, startAngle, distAngle, stepCount);
242
				self.setAngle(newAngle);
243
				stepIndex++;
244
				if (stepIndex > stepCount - 1 || newAngle < self.beginExceed || newAngle > self.endExceed) {
245
					self.endScroll();
246
					return;
247
				}
248
				setTimeout(inertiaMove, frameInterval);
249
			})();
250
		})(nowTime, startAngle, distAngle, duration);
251
	};
252
253
	Picker.prototype.quartEaseOut = function(t, b, c, d) {
254
		return -c * ((t = t / d - 1) * t * t * t - 1) + b;
255
	};
256
257
	Picker.prototype.endScroll = function() {
258
		var self = this;
259
		if (self.list.angle < self.beginAngle) {
260
			self.list.style.webkitTransition = "150ms ease-out";
261
			self.setAngle(self.beginAngle);
262
		} else if (self.list.angle > self.endAngle) {
263
			self.list.style.webkitTransition = "150ms ease-out";
264
			self.setAngle(self.endAngle);
265
		} else {
266
			var index = parseInt((self.list.angle / self.itemAngle).toFixed(0));
267
			self.list.style.webkitTransition = "100ms ease-out";
268
			self.setAngle(self.itemAngle * index);
269
		}
270
		self.triggerChange();
271
	};
272
273
	Picker.prototype.triggerChange = function(force) {
274
		var self = this;
275
		setTimeout(function() {
276
			var index = self.getSelectedIndex();
277
			var item = self.items[index];
278
			if ($.trigger && (index != self.lastIndex || force === true)) {
279
				$.trigger(self.holder, 'change', {
280
					"index": index,
281
					"item": item
282
				});
283
				//console.log('change:' + index);
284
			}
285
			self.lastIndex = index;
286
			typeof force === 'function' && force();
287
		}, 0);
288
	};
289
290
	Picker.prototype.correctAngle = function(angle) {
291
		var self = this;
292
		if (angle < self.beginAngle) {
293
			return self.beginAngle;
294
		} else if (angle > self.endAngle) {
295
			return self.endAngle;
296
		} else {
297
			return angle;
298
		}
299
	};
300
301
	Picker.prototype.setItems = function(items) {
302
		var self = this;
303
		self.items = items || [];
304
		var buffer = [];
305
		self.items.forEach(function(item) {
306
			if (item !== null && item !== undefined) {
307
				buffer.push('<li>' + (item.text || item) + '</li>');
308
			}
309
		});
310
		self.list.innerHTML = buffer.join('');
311
		self.findElementItems();
312
		self.calcElementItemPostion();
313
		self.setAngle(self.correctAngle(self.list.angle));
314
		self.triggerChange(true);
315
	};
316
317
	Picker.prototype.getItems = function() {
318
		var self = this;
319
		return self.items;
320
	};
321
322
	Picker.prototype.getSelectedIndex = function() {
323
		var self = this;
324
		return parseInt((self.list.angle / self.itemAngle).toFixed(0));
325
	};
326
327
	Picker.prototype.setSelectedIndex = function(index, duration, callback) {
328
		var self = this;
329
		self.list.style.webkitTransition = '';
330
		var angle = self.correctAngle(self.itemAngle * index);
331
		if (duration && duration > 0) {
332
			var distAngle = angle - self.list.angle;
333
			self.scrollDistAngle(Date.now(), self.list.angle, distAngle, duration);
334
		} else {
335
			self.setAngle(angle);
336
		}
337
		self.triggerChange(callback);
338
	};
339
340
	Picker.prototype.getSelectedItem = function() {
341
		var self = this;
342
		return self.items[self.getSelectedIndex()];
343
	};
344
345
	Picker.prototype.getSelectedValue = function() {
346
		var self = this;
347
		return (self.items[self.getSelectedIndex()] || {}).value;
348
	};
349
350
	Picker.prototype.getSelectedText = function() {
351
		var self = this;
352
		return (self.items[self.getSelectedIndex()] || {}).text;
353
	};
354
355
	Picker.prototype.setSelectedValue = function(value, duration, callback) {
356
		var self = this;
357
		for (var index in self.items) {
358
			var item = self.items[index];
359
			if (item.value == value) {
360
				self.setSelectedIndex(index, duration, callback);
361
				return;
362
			}
363
		}
364
	};
365
366
	if ($.fn) {
367
		$.fn.picker = function(options) {
368
			//遍历选择的元素
369
			this.each(function(i, element) {
370
				if (element.picker) return;
371
				if (options) {
372
					element.picker = new Picker(element, options);
373
				} else {
374
					var optionsText = element.getAttribute('data-picker-options');
375
					var _options = optionsText ? JSON.parse(optionsText) : {};
376
					element.picker = new Picker(element, _options);
377
				}
378
			});
379
			return this[0] ? this[0].picker : null;
380
		};
381
382
		//自动初始化
383
		$.ready(function() {
384
			$('.mui-picker').picker();
385
		});
386
	}
387
388
})(window.mui || window, window, document, undefined);
389
//end
390
/**
391
 * 弹出选择列表插件
392
 * 此组件依赖 listpcker ,请在页面中先引入 mui.picker.css + mui.picker.js
393
 * varstion 1.0.1
394
 * by Houfeng
395
 * Houfeng@DCloud.io
396
 */
397
398
(function($, document) {
399
400
	//创建 DOM
401
	$.dom = function(str) {
402
		if (typeof(str) !== 'string') {
403
			if ((str instanceof Array) || (str[0] && str.length)) {
404
				return [].slice.call(str);
405
			} else {
406
				return [str];
407
			}
408
		}
409
		if (!$.__create_dom_div__) {
410
			$.__create_dom_div__ = document.createElement('div');
411
		}
412
		$.__create_dom_div__.innerHTML = str;
413
		return [].slice.call($.__create_dom_div__.childNodes);
414
	};
415
416
	var panelBuffer = '<div class="mui-poppicker">\
417
		<div class="mui-poppicker-header">\
418
			<button class="mui-btn mui-poppicker-btn-cancel">取消</button>\
419
			<button class="mui-btn mui-btn-blue mui-poppicker-btn-ok">确定</button>\
420
			<div class="mui-poppicker-clear"></div>\
421
		</div>\
422
		<div class="mui-poppicker-body">\
423
		</div>\
424
	</div>';
425
426
	var pickerBuffer = '<div class="mui-picker">\
427
		<div class="mui-picker-inner">\
428
			<div class="mui-pciker-rule mui-pciker-rule-ft"></div>\
429
			<ul class="mui-pciker-list">\
430
			</ul>\
431
			<div class="mui-pciker-rule mui-pciker-rule-bg"></div>\
432
		</div>\
433
	</div>';
434
435
	//定义弹出选择器类
436
	var PopPicker = $.PopPicker = $.Class.extend({
437
		//构造函数
438
		init: function(options) {
439
			var self = this;
440
			self.options = options || {};
441
			self.options.buttons = self.options.buttons || ['取消', '确定'];
442
			self.panel = $.dom(panelBuffer)[0];
443
			document.body.appendChild(self.panel);
444
			self.ok = self.panel.querySelector('.mui-poppicker-btn-ok');
445
			self.cancel = self.panel.querySelector('.mui-poppicker-btn-cancel');
446
			self.body = self.panel.querySelector('.mui-poppicker-body');
447
			self.mask = $.createMask();
448
			self.cancel.innerText = self.options.buttons[0];
449
			self.ok.innerText = self.options.buttons[1];
450
			self.cancel.addEventListener('tap', function(event) {
451
				self.hide();
452
			}, false);
453
			self.ok.addEventListener('tap', function(event) {
454
				if (self.callback) {
455
					var rs = self.callback(self.getSelectedItems());
456
					if (rs !== false) {
457
						self.hide();
458
					}
459
				}
460
			}, false);
461
			self.mask[0].addEventListener('tap', function() {
462
				self.hide();
463
			}, false);
464
			self._createPicker();
465
			//防止滚动穿透
466
			self.panel.addEventListener($.EVENT_START, function(event) {
467
				event.preventDefault();
468
			}, false);
469
			self.panel.addEventListener($.EVENT_MOVE, function(event) {
470
				event.preventDefault();
471
			}, false);
472
		},
473
		_createPicker: function() {
474
			var self = this;
475
			var layer = self.options.layer || 1;
476
			var width = (100 / layer) + '%';
477
			self.pickers = [];
478
			for (var i = 1; i <= layer; i++) {
479
				var pickerElement = $.dom(pickerBuffer)[0];
480
				pickerElement.style.width = width;
481
				self.body.appendChild(pickerElement);
482
				var picker = $(pickerElement).picker();
483
				self.pickers.push(picker);
484
				pickerElement.addEventListener('change', function(event) {
485
					var nextPickerElement = this.nextSibling;
486
					if (nextPickerElement && nextPickerElement.picker) {
487
						var eventData = event.detail || {};
488
						var preItem = eventData.item || {};
489
						nextPickerElement.picker.setItems(preItem.children);
490
					}
491
				}, false);
492
			}
493
		},
494
		//填充数据
495
		setData: function(data) {
496
			var self = this;
497
			data = data || [];
498
			self.pickers[0].setItems(data);
499
		},
500
		//获取选中的项(数组)
501
		getSelectedItems: function() {
502
			var self = this;
503
			var items = [];
504
			for (var i in self.pickers) {
505
				var picker = self.pickers[i];
506
				items.push(picker.getSelectedItem() || {});
507
			}
508
			return items;
509
		},
510
		//显示
511
		show: function(callback) {
512
			var self = this;
513
			self.callback = callback;
514
			self.mask.show();
515
			document.body.classList.add($.className('poppicker-active-for-page'));
516
			self.panel.classList.add($.className('active'));
517
			//处理物理返回键
518
			self.__back = $.back;
519
			$.back = function() {
520
				self.hide();
521
			};
522
		},
523
		//隐藏
524
		hide: function() {
525
			var self = this;
526
			if (self.disposed) return;
527
			self.panel.classList.remove($.className('active'));
528
			self.mask.close();
529
			document.body.classList.remove($.className('poppicker-active-for-page'));
530
			//处理物理返回键
531
			$.back=self.__back;
532
		},
533
		dispose: function() {
534
			var self = this;
535
			self.hide();
536
			setTimeout(function() {
537
				self.panel.parentNode.removeChild(self.panel);
538
				for (var name in self) {
539
					self[name] = null;
540
					delete self[name];
541
				};
542
				self.disposed = true;
543
			}, 300);
544
		}
545
	});
546
547
})(mui, document);
548
/**
549
 * 日期时间插件
550
 * varstion 1.0.5
551
 * by Houfeng
552
 * Houfeng@DCloud.io
553
 */
554
555
(function($, document) {
556
557
	//创建 DOM
558
	$.dom = function(str) {
559
		if (typeof(str) !== 'string') {
560
			if ((str instanceof Array) || (str[0] && str.length)) {
561
				return [].slice.call(str);
562
			} else {
563
				return [str];
564
			}
565
		}
566
		if (!$.__create_dom_div__) {
567
			$.__create_dom_div__ = document.createElement('div');
568
		}
569
		$.__create_dom_div__.innerHTML = str;
570
		return [].slice.call($.__create_dom_div__.childNodes);
571
	};
572
573
	var domBuffer = '<div class="mui-dtpicker" data-type="datetime">\
574
		<div class="mui-dtpicker-header">\
575
			<button data-id="btn-cancel" class="mui-btn">取消</button>\
576
			<button data-id="btn-ok" class="mui-btn mui-btn-blue">确定</button>\
577
		</div>\
578
		<div class="mui-dtpicker-title"><h5 data-id="title-y">年</h5><h5 data-id="title-m">月</h5><h5 data-id="title-d">日</h5><h5 data-id="title-h">时</h5><h5 data-id="title-i">分</h5></div>\
579
		<div class="mui-dtpicker-body">\
580
			<div data-id="picker-y" class="mui-picker">\
581
				<div class="mui-picker-inner">\
582
					<div class="mui-pciker-rule mui-pciker-rule-ft"></div>\
583
					<ul class="mui-pciker-list">\
584
					</ul>\
585
					<div class="mui-pciker-rule mui-pciker-rule-bg"></div>\
586
				</div>\
587
			</div>\
588
			<div data-id="picker-m" class="mui-picker">\
589
				<div class="mui-picker-inner">\
590
					<div class="mui-pciker-rule mui-pciker-rule-ft"></div>\
591
					<ul class="mui-pciker-list">\
592
					</ul>\
593
					<div class="mui-pciker-rule mui-pciker-rule-bg"></div>\
594
				</div>\
595
			</div>\
596
			<div data-id="picker-d" class="mui-picker">\
597
				<div class="mui-picker-inner">\
598
					<div class="mui-pciker-rule mui-pciker-rule-ft"></div>\
599
					<ul class="mui-pciker-list">\
600
					</ul>\
601
					<div class="mui-pciker-rule mui-pciker-rule-bg"></div>\
602
				</div>\
603
			</div>\
604
			<div data-id="picker-h" class="mui-picker">\
605
				<div class="mui-picker-inner">\
606
					<div class="mui-pciker-rule mui-pciker-rule-ft"></div>\
607
					<ul class="mui-pciker-list">\
608
					</ul>\
609
					<div class="mui-pciker-rule mui-pciker-rule-bg"></div>\
610
				</div>\
611
			</div>\
612
			<div data-id="picker-i" class="mui-picker">\
613
				<div class="mui-picker-inner">\
614
					<div class="mui-pciker-rule mui-pciker-rule-ft"></div>\
615
					<ul class="mui-pciker-list">\
616
					</ul>\
617
					<div class="mui-pciker-rule mui-pciker-rule-bg"></div>\
618
				</div>\
619
			</div>\
620
		</div>\
621
	</div>';
622
623
	//plugin
624
	var DtPicker = $.DtPicker = $.Class.extend({
625
		init: function(options) {
626
			var self = this;
627
			var _picker = $.dom(domBuffer)[0];
628
			document.body.appendChild(_picker);
629
			$('[data-id*="picker"]', _picker).picker();
630
			var ui = self.ui = {
631
				picker: _picker,
632
				mask: $.createMask(),
633
				ok: $('[data-id="btn-ok"]', _picker)[0],
634
				cancel: $('[data-id="btn-cancel"]', _picker)[0],
635
				y: $('[data-id="picker-y"]', _picker)[0],
636
				m: $('[data-id="picker-m"]', _picker)[0],
637
				d: $('[data-id="picker-d"]', _picker)[0],
638
				h: $('[data-id="picker-h"]', _picker)[0],
639
				i: $('[data-id="picker-i"]', _picker)[0],
640
				labels: $('[data-id*="title-"]', _picker),
641
			};
642
			ui.cancel.addEventListener('tap', function() {
643
				self.hide();
644
			}, false);
645
			ui.ok.addEventListener('tap', function() {
646
				var rs = self.callback(self.getSelected());
647
				if (rs !== false) {
648
					self.hide();
649
				}
650
			}, false);
651
			ui.y.addEventListener('change', function(e) { //目前的change事件容易导致级联触发
652
				if (self.options.beginMonth || self.options.endMonth) {
653
					self._createMonth();
654
				} else {
655
					self._createDay();
656
				}
657
			}, false);
658
			ui.m.addEventListener('change', function(e) {
659
				self._createDay();
660
			}, false);
661
			ui.d.addEventListener('change', function(e) {
662
				if (self.options.beginMonth || self.options.endMonth) { //仅提供了beginDate时,触发day,hours,minutes的change
663
					self._createHours();
664
				}
665
			}, false);
666
			ui.h.addEventListener('change', function(e) {
667
				if (self.options.beginMonth || self.options.endMonth) {
668
					self._createMinutes();
669
				}
670
			}, false);
671
			ui.mask[0].addEventListener('tap', function() {
672
				self.hide();
673
			}, false);
674
			self._create(options);
675
			//防止滚动穿透
676
			self.ui.picker.addEventListener($.EVENT_START, function(event) {
677
				event.preventDefault();
678
			}, false);
679
			self.ui.picker.addEventListener($.EVENT_MOVE, function(event) {
680
				event.preventDefault();
681
			}, false);
682
		},
683
		getSelected: function() {
684
			var self = this;
685
			var ui = self.ui;
686
			var type = self.options.type;
687
			var selected = {
688
				type: type,
689
				y: ui.y.picker.getSelectedItem(),
690
				m: ui.m.picker.getSelectedItem(),
691
				d: ui.d.picker.getSelectedItem(),
692
				h: ui.h.picker.getSelectedItem(),
693
				i: ui.i.picker.getSelectedItem(),
694
				toString: function() {
695
					return this.value;
696
				}
697
			};
698
			switch (type) {
699
				case 'datetime':
700
					selected.value = selected.y.value + '-' + selected.m.value + '-' + selected.d.value + ' ' + selected.h.value + ':' + selected.i.value;
701
					selected.text = selected.y.text + '-' + selected.m.text + '-' + selected.d.text + ' ' + selected.h.text + ':' + selected.i.text;
702
					break;
703
				case 'date':
704
					selected.value = selected.y.value + '-' + selected.m.value + '-' + selected.d.value;
705
					selected.text = selected.y.text + '-' + selected.m.text + '-' + selected.d.text;
706
					break;
707
				case 'time':
708
					selected.value = selected.h.value + ':' + selected.i.value;
709
					selected.text = selected.h.text + ':' + selected.i.text;
710
					break;
711
				case 'month':
712
					selected.value = selected.y.value + '-' + selected.m.value;
713
					selected.text = selected.y.text + '-' + selected.m.text;
714
					break;
715
				case 'hour':
716
					selected.value = selected.y.value + '-' + selected.m.value + '-' + selected.d.value + ' ' + selected.h.value;
717
					selected.text = selected.y.text + '-' + selected.m.text + '-' + selected.d.text + ' ' + selected.h.text;
718
					break;
719
				case 'year':
720
					selected.value = selected.y.value ;
721
					selected.text = selected.y.text ;
722
					break;	
723
			}
724
			return selected;
725
		},
726
		setSelectedValue: function(value) {
727
			var self = this;
728
			var ui = self.ui;
729
			var parsedValue = self._parseValue(value);
730
			//TODO 嵌套过多,因为picker的change时间是异步(考虑到性能)的,所以为了保证change之后再setSelected,目前使用回调处理
731
			ui.y.picker.setSelectedValue(parsedValue.y, 0, function() {
732
				ui.m.picker.setSelectedValue(parsedValue.m, 0, function() {
733
					ui.d.picker.setSelectedValue(parsedValue.d, 0, function() {
734
						ui.h.picker.setSelectedValue(parsedValue.h, 0, function() {
735
							ui.i.picker.setSelectedValue(parsedValue.i, 0);
736
						});
737
					});
738
				});
739
			});
740
		},
741
		isLeapYear: function(year) {
742
			return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
743
		},
744
		_inArray: function(array, item) {
745
			for (var index in array) {
746
				var _item = array[index];
747
				if (_item === item) return true;
748
			}
749
			return false;
750
		},
751
		getDayNum: function(year, month) {
752
			var self = this;
753
			if (self._inArray([1, 3, 5, 7, 8, 10, 12], month)) {
754
				return 31;
755
			} else if (self._inArray([4, 6, 9, 11], month)) {
756
				return 30;
757
			} else if (self.isLeapYear(year)) {
758
				return 29;
759
			} else {
760
				return 28;
761
			}
762
		},
763
		_fill: function(num) {
764
			num = num.toString();
765
			if (num.length < 2) {
766
				num = 0 + num;
767
			}
768
			return num;
769
		},
770
		_isBeginYear: function() {
771
			return this.options.beginYear === parseInt(this.ui.y.picker.getSelectedValue());
772
		},
773
		_isBeginMonth: function() {
774
			return this.options.beginMonth && this._isBeginYear() && this.options.beginMonth === parseInt(this.ui.m.picker.getSelectedValue());
775
		},
776
		_isBeginDay: function() {
777
			return this._isBeginMonth() && this.options.beginDay === parseInt(this.ui.d.picker.getSelectedValue());
778
		},
779
		_isBeginHours: function() {
780
			return this._isBeginDay() && this.options.beginHours === parseInt(this.ui.h.picker.getSelectedValue());
781
		},
782
		_isEndYear: function() {
783
			return this.options.endYear === parseInt(this.ui.y.picker.getSelectedValue());
784
		},
785
		_isEndMonth: function() {
786
			return this.options.endMonth && this._isEndYear() && this.options.endMonth === parseInt(this.ui.m.picker.getSelectedValue());
787
		},
788
		_isEndDay: function() {
789
			return this._isEndMonth() && this.options.endDay === parseInt(this.ui.d.picker.getSelectedValue());
790
		},
791
		_isEndHours: function() {
792
			return this._isEndDay() && this.options.endHours === parseInt(this.ui.h.picker.getSelectedValue());
793
		},
794
		_createYear: function(current) {
795
			var self = this;
796
			var options = self.options;
797
			var ui = self.ui;
798
			//生成年列表
799
			var yArray = [];
800
			if (options.customData.y) {
801
				yArray = options.customData.y;
802
			} else {
803
				var yBegin = options.beginYear;
804
				var yEnd = options.endYear;
805
				for (var y = yBegin; y <= yEnd; y++) {
806
					yArray.push({
807
						text: y + '',
808
						value: y
809
					});
810
				}
811
			}
812
			ui.y.picker.setItems(yArray);
813
			//ui.y.picker.setSelectedValue(current);
814
		},
815
		_createMonth: function(current) {
816
			var self = this;
817
			var options = self.options;
818
			var ui = self.ui;
819
820
			//生成月列表
821
			var mArray = [];
822
			if (options.customData.m) {
823
				mArray = options.customData.m;
824
			} else {
825
				var m = options.beginMonth && self._isBeginYear() ? options.beginMonth : 1;
826
				var maxMonth = options.endMonth && self._isEndYear() ? options.endMonth : 12;
827
				for (; m <= maxMonth; m++) {
828
					var val = self._fill(m);
829
					mArray.push({
830
						text: val,
831
						value: val
832
					});
833
				}
834
			}
835
			ui.m.picker.setItems(mArray);
836
			//ui.m.picker.setSelectedValue(current);
837
		},
838
		_createDay: function(current) {
839
			var self = this;
840
			var options = self.options;
841
			var ui = self.ui;
842
843
			//生成日列表
844
			var dArray = [];
845
			if (options.customData.d) {
846
				dArray = options.customData.d;
847
			} else {
848
				var d = self._isBeginMonth() ? options.beginDay : 1;
849
				var maxDay = self._isEndMonth() ? options.endDay : self.getDayNum(parseInt(this.ui.y.picker.getSelectedValue()), parseInt(this.ui.m.picker.getSelectedValue()));
850
				for (; d <= maxDay; d++) {
851
					var val = self._fill(d);
852
					dArray.push({
853
						text: val,
854
						value: val
855
					});
856
				}
857
			}
858
			ui.d.picker.setItems(dArray);
859
			current = current || ui.d.picker.getSelectedValue();
860
			//ui.d.picker.setSelectedValue(current);
861
		},
862
		_createHours: function(current) {
863
			var self = this;
864
			var options = self.options;
865
			var ui = self.ui;
866
			//生成时列表
867
			var hArray = [];
868
			if (options.customData.h) {
869
				hArray = options.customData.h;
870
			} else {
871
				var h = self._isBeginDay() ? options.beginHours : 0;
872
				var maxHours = self._isEndDay() ? options.endHours : 23;
873
				for (; h <= maxHours; h++) {
874
					var val = self._fill(h);
875
					hArray.push({
876
						text: val,
877
						value: val
878
					});
879
				}
880
			}
881
			ui.h.picker.setItems(hArray);
882
			//ui.h.picker.setSelectedValue(current);
883
		},
884
		_createMinutes: function(current) {
885
			var self = this;
886
			var options = self.options;
887
			var ui = self.ui;
888
889
			//生成分列表
890
			var iArray = [];
891
			if (options.customData.i) {
892
				iArray = options.customData.i;
893
			} else {
894
				var i = self._isBeginHours() ? options.beginMinutes : 0;
895
				var maxMinutes = self._isEndHours() ? options.endMinutes : 59;
896
				for (; i <= maxMinutes; i++) {
897
					var val = self._fill(i);
898
					iArray.push({
899
						text: val,
900
						value: val
901
					});
902
				}
903
			}
904
			ui.i.picker.setItems(iArray);
905
			//ui.i.picker.setSelectedValue(current);
906
		},
907
		_setLabels: function() {
908
			var self = this;
909
			var options = self.options;
910
			var ui = self.ui;
911
			ui.labels.each(function(i, label) {
912
				label.innerText = options.labels[i];
913
			});
914
		},
915
		_setButtons: function() {
916
			var self = this;
917
			var options = self.options;
918
			var ui = self.ui;
919
			ui.cancel.innerText = options.buttons[0];
920
			ui.ok.innerText = options.buttons[1];
921
		},
922
		_parseValue: function(value) {
923
			var self = this;
924
			var rs = {};
925
			if (value) {
926
				var parts = value.replace(":", "-").replace(" ", "-").split("-");
927
				rs.y = parts[0];
928
				rs.m = parts[1];
929
				rs.d = parts[2];
930
				rs.h = parts[3];
931
				rs.i = parts[4];
932
			} else {
933
				var now = new Date();
934
				rs.y = now.getFullYear();
935
				rs.m = now.getMonth() + 1;
936
				rs.d = now.getDate();
937
				rs.h = now.getHours();
938
				rs.i = now.getMinutes();
939
			}
940
			return rs;
941
		},
942
		_create: function(options) {
943
			var self = this;
944
			options = options || {};
945
			options.labels = options.labels || ['年', '月', '日', '时', '分'];
946
			options.buttons = options.buttons || ['取消', '确定'];
947
			options.type = options.type || 'datetime';
948
			options.customData = options.customData || {};
949
			self.options = options;
950
			var now = new Date();
951
			var beginDate = options.beginDate;
952
			if (beginDate instanceof Date && !isNaN(beginDate.valueOf())) { //设定了开始日期
953
				options.beginYear = beginDate.getFullYear();
954
				options.beginMonth = beginDate.getMonth() + 1;
955
				options.beginDay = beginDate.getDate();
956
				options.beginHours = beginDate.getHours();
957
				options.beginMinutes = beginDate.getMinutes();
958
			}
959
			var endDate = options.endDate;
960
			if (endDate instanceof Date && !isNaN(endDate.valueOf())) { //设定了结束日期
961
				options.endYear = endDate.getFullYear();
962
				options.endMonth = endDate.getMonth() + 1;
963
				options.endDay = endDate.getDate();
964
				options.endHours = endDate.getHours();
965
				options.endMinutes = endDate.getMinutes();
966
			}
967
			options.beginYear = options.beginYear || (now.getFullYear() - 5);
968
			options.endYear = options.endYear || (now.getFullYear() + 5);
969
			var ui = self.ui;
970
			//设定label
971
			self._setLabels();
972
			self._setButtons();
973
			//设定类型
974
			ui.picker.setAttribute('data-type', options.type);
975
			//生成
976
			self._createYear();
977
			self._createMonth();
978
			self._createDay();
979
			self._createHours();
980
			self._createMinutes();
981
			//设定默认值
982
			self.setSelectedValue(options.value);
983
		},
984
		//显示
985
		show: function(callback) {
986
			var self = this;
987
			var ui = self.ui;
988
			self.callback = callback || $.noop;
989
			ui.mask.show();
990
			document.body.classList.add($.className('dtpicker-active-for-page'));
991
			ui.picker.classList.add($.className('active'));
992
			//处理物理返回键
993
			self.__back = $.back;
994
			$.back = function() {
995
				self.hide();
996
			};
997
		},
998
		hide: function() {
999
			var self = this;
1000
			if (self.disposed) return;
1001
			var ui = self.ui;
1002
			ui.picker.classList.remove($.className('active'));
1003
			ui.mask.close();
1004
			document.body.classList.remove($.className('dtpicker-active-for-page'));
1005
			//处理物理返回键
1006
			$.back = self.__back;
1007
		},
1008
		dispose: function() {
1009
			var self = this;
1010
			self.hide();
1011
			setTimeout(function() {
1012
				self.ui.picker.parentNode.removeChild(self.ui.picker);
1013
				for (var name in self) {
1014
					self[name] = null;
1015
					delete self[name];
1016
				};
1017
				self.disposed = true;
1018
			}, 300);
1019
		}
1020
	});
1021
1022
})(mui, document);