現在スマホアプリのカレンダー機能を作っているのですが、一ヶ月ごとにスクロールして現在の日付を取得しているのですが、アニメーションさせずに自由にスクロールしながら日付を取得したいです。
lang
1Object.defineProperty(Date.prototype, 'format', { 2 get: function () { 3 return function (str_format) { 4 var f = str_format; 5 var o = this; 6 if (!f) f = 'yyyy-MM-dd hh:mm:ss.SSS'; 7 var mon = ["年1月", "年2月", "年3月", "年4月", "年5月", "年6月", "年7月", "年8月", "年9月", "年10月", "年11月", "年12月"]; 8 var week = ["日","月","火","水","木","金","土"]; 9 f = f.replace(/MMM/g, '@@@@@'); 10 f = f.replace(/dddd/g, '@@@@'); 11 f = f.replace(/ddd/g, '@@@'); 12 f = f.replace(/yyyy/g, o.getFullYear()); 13 f = f.replace(/MM/g, ('0' + (o.getMonth() + 1)).slice(-2)); 14 f = f.replace(/hh/g, ('0' + o.getHours()).slice(-2)); 15 f = f.replace(/mm/g, ('0' + o.getMinutes()).slice(-2)); 16 f = f.replace(/ss/g, ('0' + o.getSeconds()).slice(-2)); 17 f = f.replace(/dd/g, ('0' + o.getDate()).slice(-2)); 18 if (f.match(/S/g)) { 19 var milliSeconds = ('00' + o.getMilliseconds()).slice(-3); 20 var length = f.match(/S/g).length; 21 for (var i = 0; i < length; i++) f = f.replace(/S/, milliSeconds.substring(i, i + 1)); 22 } 23 f = f.replace(/@@@@@/g, mon[o.getMonth()]); 24 f = f.replace(/@@@@/g, week[o.getDay()]); 25 f = f.replace(/@@@/g, week[o.getDay()].slice(3)); 26 return f; 27 }; 28 } 29}); 30 31Object.defineProperty(Date.prototype, 'add', { 32 get: function () { 33 return function (interval, str_target) { 34 35 var t = str_target.toLowerCase(); 36 var o = this; 37 38 if(t=='y' || str_target=='M'){ 39 var y, M, d; 40 y = o.getFullYear(); 41 M = o.getMonth(); /* between 0 to 11 */ 42 d = o.getDate(); 43 44 if(t=='y'){/*Year*/ 45 y += interval; 46 } 47 else{ /*Month*/ 48 M += interval; 49 y += Math.floor(M / 12); 50 M = (M + 12) % 12; 51 } 52 var max = [31, 28 + (y % 4 == 0 && (y % 100!=0 || y % 400==0)), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; 53 if(d > max[M]){ d = max[M]} 54 55 return new Date( 56 y, 57 M, 58 d, 59 o.getHours(), 60 o.getMinutes(), 61 o.getSeconds(), 62 o.getMilliseconds() 63 ); 64 } 65 66 else if(t=='d'){/*Day*/ 67 return new Date(o.getTime() + interval * 86400000); 68 } 69 else if(t=='h'){/*Hour*/ 70 return new Date(o.getTime() + interval * 3600000); 71 } 72 else if(str_target=='m'){/*Minute*/ 73 return new Date(o.getTime() + interval * 60000); 74 } 75 else if(t=='s'){/*Second*/ 76 return new Date(o.getTime() + interval * 1000); 77 } 78 else { 79 return new Date(o) 80 } 81 }; 82 } 83}); 84 85var sel_date = new Date(); 86$(function(){ 87 create_fullcal(); 88 89 //表示位置の設定 90 reposition(); 91 92 //イベント追加 93 var elm = document.getElementsByClassName("scroll-area")[0]; 94 elm.addEventListener('touchstart', touchstart); 95 elm.addEventListener('touchmove', touchmove); 96 elm.addEventListener('touchend', touchend); 97 elm.addEventListener('mousedown', dragstart); 98 window.addEventListener('mousemove', drag); 99 window.addEventListener('mouseup', touchend); 100 101 window.addEventListener('resize', reposition); 102}); 103 104function create_fullcal(){ 105 106 //タイトルを追加 107 $(".cal_title").text(sel_date.format('yyyyMMM')); 108 109 110 111 //カレンダー作成 112 var frame = $(".scroll-area"); 113 $(makeCal(sel_date.add(-2, 'M'), -1)[0].childNodes).appendTo(frame); 114 $(makeCal(sel_date.add(-1, 'M'), -1)[0].childNodes).appendTo(frame); 115 $(makeCal(sel_date, 0)[0].childNodes).appendTo(frame); 116 $(makeCal(sel_date.add(1, 'M'), 1)[0].childNodes).appendTo(frame); 117 $(makeCal(sel_date.add(2, 'M'), 1)[0].childNodes).appendTo(frame); 118} 119 120function modify_cal(flg){ 121 //タイトルを変更 122 $(".cal_title").text(sel_date.format('yyyyMMM')); 123 124 //逆方向に2ヶ月離れた月は削除対象 125 var delete_date = sel_date.add(-1 * flg * 3, 'M').format('yyyy-MM-'); 126 var delete_date2 = sel_date.add(-1 * flg * 4, 'M').format('yyyy-MM-'); 127 128 //削除対象月の日付入りのLineを削除 129 var lines = document.getElementsByClassName('scroll-area')[0].childNodes; 130 for(var i=lines.length-1; i>=0; i--){ 131 var line = lines[i]; 132 if((line.firstChild.attributes['date'].value.indexOf(delete_date)>=0 || line.firstChild.attributes['date'].value.indexOf(delete_date2)>=0) 133 && 134 (line.lastChild.attributes['date'].value.indexOf(delete_date)>=0 || line.lastChild.attributes['date'].value.indexOf(delete_date2)>=0)) 135 { 136 line.parentNode.removeChild(line); 137 } 138 } 139 140 //正方向に新しい月を追加 141 var append_elm = makeCal(sel_date.add(flg * 2, 'M'), flg); 142 var frame = $(".scroll-area"); 143 if(flg>0){ 144 $(append_elm[0].childNodes).appendTo(frame); 145 } else { 146 $(append_elm[0].childNodes).prependTo(frame); 147 } 148} 149 150function reposition(){ 151 $(".scroll-area").scrollTop(0); 152 var top; 153 var firstDay = new Date(sel_date.format('yyyy-MM-01')); 154 if(firstDay.getDay()==0){ 155 top = $("[date='"+firstDay.add(-7,'d').format('yyyy-MM-dd')+"']").parent().position().top; 156 } else { 157 top = $("[date='"+sel_date.format('yyyy-MM-01')+"']").parent().position().top; 158 } 159 $(".scroll-area").scrollTop(top); 160} 161 162var touch_pos = {}; 163function touchstart(e){ 164 if(e.touches.length > 1 || touch_pos.start) return; 165 touch_pos = { 166 scrollPos: $(".scroll-area").scrollTop(), 167 start: e.touches[0].pageY, 168 pos: e.touches[0].pageY 169 }; 170} 171 172function dragstart(e){ 173 if(touch_pos.start) return; 174 touch_pos = { 175 scrollPos: $(".scroll-area").scrollTop(), 176 start: e.pageY, 177 pos: e.pageY 178 }; 179} 180 181function touchmove(e){ 182 if (e.touches.length > 1 || !touch_pos.start) return; 183 var pos = e.touches[0].pageY; 184 $(".scroll-area").scrollTop(touch_pos.scrollPos + (touch_pos.start - pos)); 185 touch_pos.pos = pos; 186 e.preventDefault(); /* Disable 'pull to refresh' for Android Chrome */ 187} 188 189function drag(e){ 190 if (!touch_pos.start) return; 191 if (e.buttons == 0){ touch_pos = {}; return; } 192 var pos = e.pageY; 193 $(".scroll-area").scrollTop(touch_pos.scrollPos + (touch_pos.start - pos)); 194 touch_pos.pos = pos; 195} 196 197 198 199// アニメーション 200function touchend(e){ 201 var limit = $(".scroll-area").height() * 0.33; 202 if(Math.abs(touch_pos.start - touch_pos.pos) > limit){ 203 var sgn = Math.sign(touch_pos.start - touch_pos.pos); 204 //表示位置の設定 205 var top = $("[date='"+sel_date.add(sgn, 'M').format('yyyy-MM-01')+"']").parent().position().top; 206 $(".scroll-area").animate({scrollTop:$(".scroll-area").scrollTop() + top}, 200, 'linear', 207 function(){ 208 sel_date = sel_date.add(sgn, 'M'); 209 //カレンダーの再作成 210 modify_cal(sgn); 211 //表示位置の設定 212 reposition(); 213 // touch_pos = {}; 214 } 215 ); 216 } else { 217 // 元の場所に戻す(ぼよよーん) 218 $(".scroll-area").animate({scrollTop:touch_pos.scrollPos}, 200, 'linear'); 219 touch_pos = {}; 220 } 221} 222// アニメーション 223 224 225function makeCal(date, flg){ 226 var frame = $("<div/>"); 227 228 //年月を取得する 229 var this_year = date.getFullYear(); 230 var this_month = date.getMonth() + 1; 231 232 //1日の曜日を取得する 233 var first_day = (new Date(this_year, this_month -1, 1)); 234 235 var start_week = first_day.getDay(); 236 237 var start_day, end_day; 238 239 if(flg == -1){ //先月用 240 //同じ週の日曜日の日付を取得する 241 start_day = first_day.add(-1 * first_day.getDay(), 'd'); 242 //末日の曜日ぶん引く 243 end_day = first_day.add(1,'M').add(-1,'d'); 244 if(end_day.getDay() < 6){ 245 end_day = end_day.add(-1 * end_day.getDay() - 1, 'd'); 246 } 247 } else 248 if(flg == 0){ 249 //同じ週の日曜日の日付を取得する 250 start_day = first_day.add(-1 * first_day.getDay(), 'd'); 251 //末日の取得 252 end_day = first_day.add(1,'M').add(-1,'d'); 253 } else 254 if(flg == 1){ //来月用 255 //末日の取得 256 end_day = first_day.add(1,'M').add(-1,'d'); 257 //開始日を次の週の日曜日にする 258 if(first_day.getDay() > 0){ 259 first_day = first_day.add(7-first_day.getDay(), 'd'); 260 start_week = first_day.getDay(); 261 } 262 start_day = first_day; 263 } 264 265 //日曜日から先月の末まで追加 266 var line = $('<div class="week-line"/>'); 267 for(var i=0; i<start_week; i++){ 268 var day = start_day.add(i, 'd'); 269 $('<div class="days" date="'+ day.format('yyyy-MM-dd') +'">'+ '<span>' + day.getDate() + '</span>' + '</div>').appendTo(line); 270 if(day.getDay()==6){ 271 line.appendTo(frame); 272 line = $('<div class="week-line"/>'); 273 } 274 } 275 276 //今月の1日から末まで順に追加 277 for(var i=0, day=first_day; day.getDate() < end_day.getDate(); i++){ 278 day = first_day.add(i, 'd'); 279 $('<div class="days" date="'+ day.format('yyyy-MM-dd') +'">'+ '<span>' + day.getDate() + '</span>' + '</div>').appendTo(line); 280 if(day.getDay()==6){ 281 line.appendTo(frame); 282 line = $('<div class="week-line"/>'); 283 } 284 } 285 286 //末日の曜日を取得 287 var end_week = end_day.getDay(); 288 289 //土曜日までの残りの枠を次の月頭で埋める 290 for(var i=(end_week+1), j=1; i<7; i++, j++){ 291 var day = end_day.add(j, 'd'); 292 $('<div class="days" date="'+ day.format('yyyy-MM-dd') +'">' + day.getDate() + '</div>').appendTo(line); 293 if(day.getDay()==6){ 294 line.appendTo(frame); 295 line = $('<div class="week-line"/>'); 296 } 297 } 298 return frame; 299} 300
lang
1 <div class='cal_frame'> 2 <div class='cal_title'></div> 3 <div class='week-line'></div> 4 <div class='scroll-area'></div> 5 </div>
おそらく
// アニメーション のコメントアウトが入っているところが原因だと思うのですが・・・
うまく日付を取得する機能とアニメーションが切り離せなくて困っています。
お願いいたします!
あなたの回答
tips
プレビュー