🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

919閲覧

clearTimeoutが効かない。

muratariku

総合スコア11

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

1グッド

1クリップ

投稿2019/12/31 19:07

目的

「先月」と「来月」のボタンを押したらカレンダーがその月に変わるようにしたい。

問題点

「先月」と「来月」のボタンを押しても、一瞬だけその月のカレンダーが表示されただけですぐに現在の月のカレンダーになってしまうこと。

僕のコード

https://github.com/muramura-cloud/calendar

JavaScript

1'use strict'; 2 3//自作カレンダー 4//多分だけどその月の日数によってカレンダーのセルを生成できるようにする必要がある。 5//つまりfor文だけでなくwhile文も使う必要がある。 6{ 7 const table=document.getElementById('tbody'); 8 const monthLabel=document.getElementById('monthLabel'); 9 const prev=document.getElementById('prev'); 10 const next=document.getElementById('next'); 11 12 //月ごとにおける日数についてのオブジェクト 13 const monthBox={ 14 1:31, 15 2:28, 16 3:31, 17 4:30, 18 5:31, 19 6:30, 20 7:31, 21 8:31, 22 9:30, 23 10:31, 24 11:30, 25 12:31, 26 } 27 28 //月選びボタンの設定かつここで月の日数が確定する。 29 let monthForDays; 30 let daysOfMonth; 31 const selectMonth=document.getElementById('selectMonth'); 32 const selectBtn=document.getElementById('selectBtn'); 33 selectBtn.addEventListener('click',()=>{ 34 monthForDays=parseInt(getSelectValue('selectMonth')); 35 daysOfMonth=monthBox[monthForDays]; 36 while(table.firstChild) {// #choicesの中に要素があるなら 37 table.removeChild(table.firstChild);//#choicesの中に要素がなくなるまで要素を消す。 38 } 39 setWeekHead(); 40 setWeek(daysOfMonth,monthForDays); 41 setMonthLabel(monthForDays); 42 console.log(monthForDays); 43 console.log(daysOfMonth); 44 }); 45 function getSelectValue(name) { 46 const result=[]; 47 const opts=document.getElementById(name).options; 48 for(let i=0;i<opts.length;i++) { 49 const opt=opts.item(i); 50 if(opt.selected) { 51 result.push(opt.value); 52 } 53 } 54 return result; 55 } 56 57 //現在日時を生成する 58 const now=document.getElementById('now'); 59 const dayOfTheWeeks=['日','月','火','水','木','金','土']; 60 let month; 61 let date; 62 function timer() { 63 const d=new Date(); 64 const year=d.getFullYear(); 65 month=d.getMonth()+1; 66 date=d.getDate(); 67 const day=d.getDay(); 68 const h=d.getHours(); 69 const m=d.getMinutes(); 70 const s=d.getSeconds(); 71 now.textContent=`${year}${month}${date}日(${dayOfTheWeeks[day]}) ${h}時:${m}${s}` 72 setTimeout(()=>{ 73 timer(); 74 },1000); 75 } 76 timer(); 77 78 function setDaysOfMonth() { 79 monthForDays=month; 80 daysOfMonth=monthBox[monthForDays]; 81 } 82 setDaysOfMonth(); 83 console.log(monthForDays); 84 console.log(daysOfMonth); 85 86 //monthLabelの設定 87 function setMonthLabel(monthForDays) { 88 monthLabel.textContent=`${monthForDays}`; 89 } 90 setMonthLabel(monthForDays); 91 92 93 //カレンダーの曜日セルを生成する 94 function setWeekHead() { 95 const weekHead=document.createElement('tr'); 96 weekHead.classList.add('week-head'); 97 // const dayOfTheWeeks=['月','火','水','木','金','土','日']; 98 for(let i=0;i<7;i++) { 99 const dayOfTheWeek=document.createElement('th'); 100 dayOfTheWeek.classList.add('day-of-the-week'); 101 dayOfTheWeek.textContent=dayOfTheWeeks[i]; 102 weekHead.appendChild(dayOfTheWeek); 103 } 104 table.appendChild(weekHead); 105 } 106 setWeekHead(); 107 108 //カレンダーの日にちセルを生成する 109 function setWeek(daysOfMonth,monthForDays) { 110 let weekCount=1; 111 while (daysOfMonth>weekCount) { 112 const week=document.createElement('tr'); 113 week.classList.add('week'); 114 for(let i=0;i<7;i++) { 115 if(daysOfMonth<weekCount) { 116 break; 117 } 118 const td=document.createElement('td'); 119 td.textContent=weekCount; 120 if(weekCount===date&&month===monthForDays) { 121 td.classList.add('today'); 122 } 123 weekCount++; 124 week.appendChild(td); 125 } 126 table.appendChild(week); 127 } 128 } 129 setWeek(daysOfMonth,monthForDays); 130 131 //先月と来月ボタンの設定 132 prev.addEventListener('click',()=>{ 133 monthForDays--; 134 daysOfMonth=monthBox[monthForDays]; 135 if(monthForDays<1) { 136 monthForDays=12; 137 daysOfMonth=monthBox[monthForDays]; 138 } 139 while(table.firstChild) {// #choicesの中に要素があるなら 140 table.removeChild(table.firstChild);//#choicesの中に要素がなくなるまで要素を消す。 141 } 142 setWeekHead(); 143 setWeek(daysOfMonth,monthForDays); 144 setMonthLabel(monthForDays); 145 console.log(monthForDays); 146 }); 147 next.addEventListener('click',()=>{ 148 monthForDays++; 149 daysOfMonth=monthBox[monthForDays]; 150 if(monthForDays>12) { 151 monthForDays=1; 152 daysOfMonth=monthBox[monthForDays]; 153 } 154 while(table.firstChild) {// #choicesの中に要素があるなら 155 table.removeChild(table.firstChild);//#choicesの中に要素がなくなるまで要素を消す。 156 } 157 setWeekHead(); 158 setWeek(daysOfMonth,monthForDays); 159 setMonthLabel(monthForDays); 160 console.log(monthForDays); 161 }); 162}

試したこと

僕は「先月」と「来月」のボタンを押しても、一瞬だけその月のカレンダーが表示されただけですぐに現在の月のカレンダーになってしまうことから、1秒ごとに処理されるタイマー処理に原因があると思いました。しかし、それを改善する手段が思いつきませんでした。1秒ごとに現在の月を取得するtimer()があるのですけど、これがおそらく「先月」と「来月」のボタンで表示されるはずの月になってしまっているのではないかと思います。しかしsetDaysOfMonth()は一回しか呼び出していないのでそんなはずはないと思うのですが。

自分はプログラミング初学者です。このコードはチュートリアルを真似たものではなく自分で1から書いたので解りにくかったらすみません。書き方がおかしいところがあったら教えてくださるとありがたいです。

DrqYuto👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

htmlでbuttonで「先月」と「来月」のボタンを作成していいました。button
を押すと無条件でページが更新されることで結果的に元のページになってしまったと自己解決しました!

投稿2019/12/31 19:42

muratariku

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問