質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

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

Q&A

解決済

2回答

1508閲覧

javascriptで表示するカレンダーでのDOM clickイベントの問題

shutainer

総合スコア11

JavaScript

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

0グッド

0クリップ

投稿2019/08/19 15:28

前提・実現したいこと

https://qiita.com/kan_dai/items/b1850750b883f83b9bee
を参考に、JSでカレンダー機能を実装しています。

ボタンで変更できるところまで行ったのですが、日付をクリックするところを
独自の方法で、DOMでコンソール表示するところでうまくいきません。
DOMのせレクターで,querySelector('td')として、
特定の日付をとりだそうとしているのですが、できません。
なおここを('tr')とすると、一行目の曜日(日から土)はくりっくできるようになります。
querySelectorで引数にtdを指定すれば、日付にアクションを設定できる気がするのですが、
なぜでしょうか?

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

js

'use strict'; { //曜日 const weeks = ['日', '月', '火', '水', '木', '金', '土']; //現在日付 const date = new Date(); //現在西暦 let year = date.getFullYear(); //現在月 let month = date.getMonth() + 1; //表示月数 const config = { show: 3, }; //関数 カレンダー表示 function showCalender(year, month) { for (let i = 0; i < config.show; i++) { const calenderHtml = createCalender(year, month); const sec = document.createElement('section'); sec.innerHTML = calenderHtml; document.querySelector('#calender').appendChild(sec); month++; if (month > 12) { year++; month = 1; } } } //関数 カレンダー作成 function createCalender(year, month) { //つき最初の日の情報 const startDate = new Date(year, month - 1, 1); //付き最後の日の情報 const endDate = new Date(year, month, 0); //月の末日 const endDayCount = endDate.getDate(); //前月最後の日の情報 const lastMonthEndDate = new Date(year, month - 1, 0); //前月末日 const lastMonthendDayCount = lastMonthEndDate.getDate(); //月の最初の日の曜日を取得 const startDay = startDate.getDay(); //日にちのカウント変数宣言 let dayCount = 1; //html変数宣言 let calenderHtml = ''; calenderHtml += '<h1>' + year + '/' + month + '</h1>'; calenderHtml += '<table>'; //曜日を並べる for (let i = 0; i < weeks.length; i++) { calenderHtml += '<td>' + weeks[i] + '</td>'; } //日付を並べる for (let w = 0; w < 6; w++) { calenderHtml += '<tr>'; for (let d = 0; d < 7; d++) { if (w == 0 && d < startDay) { let num = lastMonthendDayCount - startDay + d + 1; calenderHtml += '<td class="is-disabled">' + num + '</td>'; } else if (dayCount > endDayCount) { let num = dayCount - endDayCount; calenderHtml += '<td class="is-disabled">' + num + '</td>'; dayCount++; } else { calenderHtml += '<td>' + dayCount + '</td>'; dayCount++; } } calenderHtml += '</tr>'; } calenderHtml += '</table>'; return calenderHtml; } function moveCalender(e) { document.querySelector('#calender').innerHTML = ''; if (e.target.id === 'prev') { month--; if (month < 1) { year--; month = 12; } } if (e.target.id === 'next') { month++; if (month > 12) { year++; month = 1; } } showCalender(year, month); } document.querySelector('#prev').addEventListener('click', moveCalender); document.querySelector('#next').addEventListener('click', moveCalender); showCalender(year, month); const dayClick = document.querySelector('td'); dayClick.addEventListener('click', function() { console.log('クリックされました'); }, false); }
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>calender_test</title> <link rel="stylesheet" href="css/styles.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> </head> <body> <button type="button" name="button" id="prev">前月</button> <button type="button" name="button" id="next">次月</button> <div id="calender"> </div> <div class="timerange"> <table> <tr> <th></th><th>予約枠</th> </tr> <tr> <td>9:00</td><td>5/5</td> </tr> <tr> <td>10:00</td><td>5/5</td> </tr> <tr> <td>11:00</td><td>5/5</td> </tr> <tr> <td>13:00</td><td>5/5</td> </tr> <tr> <td>14:00</td><td>5/5</td> </tr> <tr> <td>15:00</td><td>5/5</td> </tr> <tr> <td>16:00</td><td>5/5</td> </tr> </table> </div> <script src="js/script*.js"> </script> </body> </html>

試したこと

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

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

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

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

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

guest

回答2

0

解決しました。
for文で日付を入れる箇所で,class属性をつけ、data-setを付与しているのに気づきました。これをDOMで操作しているのですね、理解できました。

以下の内容ですね。
https://into-the-program.com/js/dataset.php

(省略) 'use strict'; { //曜日 const weeks = ['日', '月', '火', '水', '木', '金', '土']; //現在日付 const date = new Date(); //現在西暦 let year = date.getFullYear(); //現在月 let month = date.getMonth() + 1; //表示月数 const config = { show: 3, }; //関数 カレンダー表示 function showCalender(year, month) { for (let i = 0; i < config.show; i++) { const calenderHtml = createCalender(year, month); const sec = document.createElement('section'); sec.innerHTML = calenderHtml; document.querySelector('#calender').appendChild(sec); month++; if (month > 12) { year++; month = 1; } } } //関数 カレンダー作成 function createCalender(year, month) { //つき最初の日の情報 const startDate = new Date(year, month - 1, 1); //付き最後の日の情報 const endDate = new Date(year, month, 0); //月の末日 const endDayCount = endDate.getDate(); //前月最後の日の情報 const lastMonthEndDate = new Date(year, month - 1, 0); //前月末日 const lastMonthendDayCount = lastMonthEndDate.getDate(); //月の最初の日の曜日を取得 const startDay = startDate.getDay(); //日にちのカウント変数宣言 let dayCount = 1; //html変数宣言 let calenderHtml = ''; calenderHtml += '<h1>' + year + '/' + month + '</h1>'; calenderHtml += '<table>'; //曜日を並べる for (let i = 0; i < weeks.length; i++) { calenderHtml += '<td>' + weeks[i] + '</td>'; } //日付を並べる for (let w = 0; w < 6; w++) { calenderHtml += '<tr>'; for (let d = 0; d < 7; d++) { if (w == 0 && d < startDay) { let num = lastMonthendDayCount - startDay + d + 1; calenderHtml += '<td class="is-disabled">' + num + '</td>'; } else if (dayCount > endDayCount) { let num = dayCount - endDayCount; calenderHtml += '<td class="is-disabled">' + num + '</td>'; dayCount++; } else { calenderHtml += `<td class="calendar_td" data-date="${year}/${month}/${dayCount}">${dayCount}</td>`; dayCount++; } } calenderHtml += '</tr>'; } calenderHtml += '</table>'; return calenderHtml; } function moveCalender(e) { document.querySelector('#calender').innerHTML = ''; if (e.target.id === 'prev') { month--; if (month < 1) { year--; month = 12; } } if (e.target.id === 'next') { month++; if (month > 12) { year++; month = 1; } } showCalender(year, month); } document.querySelector('#prev').addEventListener('click', moveCalender); document.querySelector('#next').addEventListener('click', moveCalender); document.addEventListener("click", function(e) { if(e.target.classList.contains("calendar_td")) { alert('クリックした日付は' + e.target.dataset.date + 'です'); } }); showCalender(year, month); }

投稿2019/08/20 03:58

shutainer

総合スコア11

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

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

0

ベストアンサー

querySelectorはセレクタに一致する、文書内の最初の Element を返します。
なので、一つ目の「日」をクリックすると反応しています。

【Document.querySelector() - Web API | MDN】
https://developer.mozilla.org/ja/docs/Web/API/Document/querySelector

Document の querySelector() メソッドは、指定されたセレクターまたはセレクターのグループに一致する、文書内の最初の Element を返します。


どのように処理したいのかがわからないのでざっくり書くと2通りの方法があります。
0. 各日付にイベントをつけて回る(各日付をうまくセレクトしてaddEventListenerでイベントを付ける)
0. tableにイベントを付けてイベント発生元を捕まえる

後者のほうが難しいですが、イベントがどのように処理されるかを理解しておくとよいと思います。

【DOMイベントのキャプチャ/バブリングを整理する 〜 JSおくのほそ道 #017 - Qiita】
https://qiita.com/hosomichi/items/49500fea5fdf43f59c58

投稿2019/08/19 16:12

kei344

総合スコア69366

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

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

shutainer

2019/08/20 02:20

>kei344 ご回答ありがとうございます。 tdの最初の要素なのですね。 qiitaの記事のように日付のみにイベントを設定したいのですが、記事の 内容の理解が足りません。function(e) のeとは、イベントのオブジェクトのことを指しているのでしょうか?また、calender_tdとは何を意味するのか?(このようなタグがあるのか?) 精進します。
kei344

2019/08/20 02:31

「function(e) のeとは」文脈によりますが、提示されているコードで使われている物はイベントオブジェクトでよいです。 「calender_td」はコード中でtd要素に付与しているクラス名です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問