add demo
[LunarCalendar.git] / demo / calendar / js / calendar.js
1 window.HuangLi = window.HuangLi || {};
2
3 (function () {
4 var mobile = {
5 platform: '',
6 version: 0,
7 Android: function () {
8 return this.platform === 'Android';
9 },
10 iOS: function () {
11 return this.platform === 'iOS';
12 },
13 init: function () {
14 var ua = navigator.userAgent;
15 if (ua.match(/Android/i)) {
16 this.platform = 'Android';
17 this.version = parseFloat(ua.slice(ua.indexOf("Android") + 8));
18 }
19 else if (ua.match(/iPhone|iPad|iPod/i)) {
20 this.platform = 'iOS';
21 this.version = parseFloat(ua.slice(ua.indexOf("OS") + 3));
22 }
23 }
24 };
25 mobile.init();
26 this.mobile = mobile;
27 } ());
28
29 (function() {
30 /**
31 * 动态加载js文件
32 * @param {string} url js文件的url地址
33 * @param {Function} callback 加载完成后的回调函数
34 */
35 var _getScript = function(url, callback) {
36 var head = document.getElementsByTagName('head')[0],
37 js = document.createElement('script');
38
39 js.setAttribute('type', 'text/javascript');
40 js.setAttribute('src', url);
41
42 head.appendChild(js);
43
44 //执行回调
45 var callbackFn = function(){
46 if(typeof callback === 'function'){
47 callback();
48 }
49 };
50
51 if (document.all) { //IE
52 js.onreadystatechange = function() {
53 if (js.readyState == 'loaded' || js.readyState == 'complete') {
54 callbackFn();
55 }
56 }
57 } else {
58 js.onload = function() {
59 callbackFn();
60 }
61 }
62 }
63
64 //如果使用的是zepto,就添加扩展函数
65 if(Zepto){
66 $.getScript = _getScript;
67 }
68 })();
69
70
71 (function () {
72 var Footprint = function () {};
73 // Default template settings, uses ASP/PHP/JSP delimiters, change the
74 // following template settings to use alternative delimiters.
75 var templateSettings = {
76 evaluate : /<%([\s\S]+?)%>/g,
77 interpolate : /<%=([\s\S]+?)%>/g
78 };
79
80 // JavaScript micro-templating, similar to John Resig's implementation.
81 // Underscore templating handles arbitrary delimiters, preserves whitespace,
82 // and correctly escapes quotes within interpolated code.
83 Footprint.compile = function(str, settings) {
84 var c = settings || templateSettings;
85 var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
86 'with(obj||{}){__p.push(\'' +
87 str.replace(/\\/g, '\\\\')
88 .replace(/'/g, "\\'")
89 .replace(c.interpolate, function(match, code) {
90 return "'," + code.replace(/\\'/g, "'") + ",'";
91 })
92 .replace(c.evaluate || null, function(match, code) {
93 return "');" + code.replace(/\\'/g, "'")
94 .replace(/[\r\n\t]/g, ' ') + "__p.push('";
95 })
96 .replace(/\r/g, '\\r')
97 .replace(/\n/g, '\\n')
98 .replace(/\t/g, '\\t')
99 + "');}return __p.join('');";
100 return new Function('obj', tmpl);
101 };
102
103 // Preserves template method for compatible with legacy call.
104 Footprint.template = function (str, data) {
105 var compilied = Footprint.compile(str);
106 return compilied(data);
107 };
108
109 if (typeof exports !== "undefined") {
110 exports.Footprint = Footprint;
111 } else {
112 window.Footprint = Footprint;
113 }
114
115 //如果使用的是zepto,就添加扩展函数
116 if(Zepto){
117 $.template = Footprint.template;
118 }
119 }());
120
121 var Calendar = (function(){
122 var hlurl = 'http://cdn.tuijs.com/js/';
123 var hlMinYear = 2008;
124 var hlMaxYear = 2020;
125 var minYear = 1891;//最小年限
126 var maxYear = 2100;//最大年限
127 var itemTemp = [
128 '<div class="date_item<%=itemCls%>" data-index="<%=index%>">',
129 ' <span class="date_icon<%=iconCls%>"><%=iconText%></span>',
130 ' <span class="date_day"><%=day%></span>',
131 ' <span class="date_lunar<%=fetvCls%>"><%=lunar%></span>',
132 '</div>'
133 ];
134
135 var now = new Date();
136 var current = null;
137 var DATA = null;
138 var panel = [0,1]; //当前显示面板panel[0]
139 var pageWidth = 0; //设备宽度
140 var slideIng = false; //是否滑动中
141 var timer = -1;
142
143 var formateDayD4 = function(month,day){
144 month = month+1;
145 month = month<10 ? '0'+month : month;
146 day = day<10 ? '0'+day : day;
147 return 'd'+month+day;
148 };
149
150 function formatDate(){
151 if(!current)return '';
152 var year = current.year;
153 var month = current.month;
154 var day = current.day;
155 month = month<10 ? '0'+month : month;
156 day = day<10 ? '0'+day : day;
157 return year+'-'+month+'-'+day;
158 };
159
160 function setCurrentByNow(year,month,day,pos){
161 current = {
162 year : year || now.getFullYear(),
163 month : month || now.getMonth()+1,
164 day : day || now.getDate(),
165 pos : pos || 0
166 };
167 };
168
169 //黄历
170 function getHL(){
171 if(HuangLi['y'+current.year]){ //该年已有黄历数据
172 var hl = HuangLi['y'+current.year][formateDayD4(current.month,current.day)];
173 showHL(hl);
174 }else if(current.year>=hlMinYear && current.year<=hlMaxYear){
175 $.getScript(hlurl+'hl'+current.year+'.min.js',function(){
176 var hl = HuangLi['y'+current.year][formateDayD4(current.month,current.day)];
177 showHL(hl);
178 });
179 }
180 }
181 function showHL(hl){
182 if(hl){
183 $('.hl_y_content').html(hl.y);
184 $('.hl_j_content').html(hl.j);
185 $('.date_hl').show();
186 }else{
187 $('.date_hl').hide();
188 }
189 };
190
191 function showInfo(_this){
192 var currentLunar = LunarCalendar.solarToLunar(current.year,current.month,current.day);
193 var weekday = new Date(current.year,current.month-1,current.day).getDay();
194 var weekList = ['日','一','二','三','四','五','六'];
195 $('#toolbar h1').html(formatDate());
196 $('.date_lunar_info').html('农历'+currentLunar.lunarMonthName+currentLunar.lunarDayName+' 星期'+weekList[weekday]);
197 $('.date_gan_zhi').html(currentLunar.GanZhiYear+'年['+currentLunar.zodiac+'年] '+currentLunar.GanZhiMonth+'月 '+currentLunar.GanZhiDay+'日');
198
199 var fetv = [];
200 if(currentLunar.term) fetv.push(currentLunar.term);
201 if(currentLunar.lunarFestival) fetv.push(currentLunar.lunarFestival);
202 if(currentLunar.solarFestival) fetv.push(currentLunar.solarFestival.split(' '));
203 $('.date_fetv').html(fetv.length>0 ? '节假日纪念日:'+fetv.join(',') : '');
204
205 //当前日期
206 if(_this){
207 _this.attr('class','date_item date_current');
208 }
209
210 //拉取黄历
211 getHL();
212 };
213
214 //恢复指定日期的状态信息
215 function resetInfo(){
216 //今天
217 var oldObj = $('#date_list_'+panel[0]).find('.date_item').eq(current.pos);
218 if(now.getFullYear()==current.year && now.getMonth()+1==current.month && now.getDate()==current.day){
219 oldObj.attr('class','date_item date_today');
220 }else{
221 oldObj.attr('class','date_item');
222 }
223 };
224
225 function showDate(){
226 DATA = LunarCalendar.calendar(current.year,current.month,true);
227
228 var dateHtml = '';
229 var temp = itemTemp.join('');
230
231 for(var i=0;i<DATA.monthData.length;i++){
232 var itemData = DATA.monthData[i];
233
234 if(i%7==0){ //某行第一列
235 dateHtml+='<div class="date_row">'
236 };
237
238 var extendObj = {
239 index : i,
240 itemCls: '',
241 iconCls: itemData.worktime ? (itemData.worktime==1 ? ' worktime' : ' holiday') : '',
242 iconText: itemData.worktime ? (itemData.worktime==1 ? '班' : '休') : '',
243 fetvCls: (itemData.lunarFestival || itemData.term) ? ' lunar_fetv' : (itemData.solarFestival ? ' solar_fetv' : ''),
244 lunar: ''
245 };
246
247 var itemCls = '';
248 if(now.getFullYear()==itemData.year && now.getMonth()+1==itemData.month && now.getDate()==itemData.day){
249 itemCls = ' date_today';
250 }
251 if(current.year==itemData.year && current.month==itemData.month && current.day==itemData.day){ //当前选中
252 itemCls = ' date_current';
253 current.pos = i;
254 }
255 if(i<DATA.firstDay || i>=DATA.firstDay+DATA.monthDays){ //非本月日期
256 itemCls = ' date_other';
257 }
258 extendObj.itemCls = itemCls;
259
260 var lunar = itemData.lunarDayName;
261 //以下判断根据优先级
262 if(itemData.solarFestival) lunar = itemData.solarFestival;
263 if(itemData.lunarFestival) lunar = itemData.lunarFestival;
264 if(itemData.term) lunar = itemData.term;
265 extendObj.lunar = lunar;
266
267 $.extend(itemData,extendObj);
268
269 dateHtml += $.template(temp,itemData);
270
271 if(i%7==6){//某行尾列
272 dateHtml+='</div>';
273 };
274 };
275
276 $('#date_list_'+panel[0]).html(dateHtml);
277
278 showInfo();
279 };
280
281 //切换月份,可指定
282 function pageDate(offset,_year,_month,_day){
283 var year,month,day;
284 if(_year && _month){ //直接指定
285 year = _year;
286 month = _month;
287 }else{
288 if(current.month+offset<1){ //上一年
289 year = current.year-1;
290 month = 12;
291 }else if(current.month+offset>12){ //下一年
292 year = current.year+1;
293 month = 1;
294 }else{
295 year = current.year;
296 month = current.month+offset;
297 }
298 }
299 day = _day ? _day : (current.day > LunarCalendar.getSolarMonthDays[month-1] ? LunarCalendar.getSolarMonthDays[month-1] : current.day);
300 if(year<minYear || year>maxYear)return; //超过范围
301
302 setCurrentByNow(year,month,day);
303 changePanel();
304 showDate();
305
306 slide(offset);
307 };
308 function changePanel(){
309 var first = panel.shift();
310 panel.push(first);
311 };
312 //滑动
313 function slide(offset){
314 timer && clearTimeout(timer);
315 setSlidePos({time:0,pos:0});
316 $('#date_list_'+panel[0]).css({left:offset * pageWidth}); //将要显示
317 $('#date_list_'+panel[1]).css({left:0}); //当前显示
318
319 if(offset>0){//左滑
320 timer = setTimeout(function(){
321 setSlidePos({time:300,pos:pageWidth * -1});
322 },50);
323 }else{ //右滑
324 timer = setTimeout(function(){
325 setSlidePos({time:300,pos:pageWidth});
326 },50);
327 }
328 };
329 function setSlidePos(opt){
330 var slide = $('.date_slide')[0];
331 slide.style.webkitTransitionDuration = opt.time+'ms';
332 setTranslate(slide,opt.pos);
333 };
334 function setTranslate(obj,pos){
335 if(mobile.platform=='iOS'){//iOS下启用3d加速,安卓下有BUG,使用2d
336 obj.style.webkitTransform = 'translate3d('+pos+'px,0px,0px)';
337 }else{
338 obj.style.webkitTransform = 'translate('+pos+'px,0px)';
339 }
340 };
341
342 function addEvent(){ //base hammer.js
343 $('.date_list').hammer().on('tap','.date_item',function(){
344 var index = $(this).attr('data-index');
345 index = parseInt(index,10);
346 var itemData = DATA.monthData[index];
347
348 if(index<DATA.firstDay){ //上一个月
349 pageDate(-1,itemData.year,itemData.month,itemData.day);
350 }else if(index>=DATA.firstDay+DATA.monthDays){//下一个月
351 pageDate(1,itemData.year,itemData.month,itemData.day);
352 }else{
353 resetInfo();
354 setCurrentByNow(itemData.year,itemData.month,itemData.day,index);
355 showInfo($(this));
356 }
357 });
358
359 $('.today').hammer().on('tap',function(event){
360 pageDate(1,now.getFullYear(),now.getMonth()+1,now.getDate());
361 return false;
362 });
363
364 $('.slide_wrap').hammer().on('swipeleft',function(event){
365 pageDate(1);
366 event.preventDefault();
367 event.gesture.preventDefault();
368 return false;
369 });
370
371 $('.slide_wrap').hammer().on('swiperight',function(event){
372 pageDate(-1);
373 event.preventDefault();
374 event.gesture.preventDefault();
375 return false;
376 });
377 };
378
379 function initPageElm(){
380 pageWidth = $(document).width();
381 var panelElm0 = $('.date_list').eq(0);
382 var panelElm1 = $('.date_list').eq(1);
383 panelElm0.css('width',pageWidth);
384 panelElm1.css({'width':pageWidth,'left':pageWidth});
385 if(mobile.platform=='iOS'){//iOS启用3d,同时将子元素也设置一下,防止BUG
386 setTranslate(panelElm0[0],0);
387 setTranslate(panelElm0[1],0);
388 }
389 };
390
391 function init(){
392 initPageElm();
393 addEvent();
394 setCurrentByNow();
395 showDate();
396 };
397
398 return {
399 init : init
400 };
401 })();
402
403 $(function(){
404 Calendar.init();
405 });