riotcitybluescountrygirl
@riotcitybluescountrygirl

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

jqueryの宣言場所に関して

解決したいこと

jqueryを宣言するとjsの関数の一部がが動かなくなり困っています。

発生している問題・エラー

Uncaught ReferenceError: nextMonth is not defined
jqueryの宣言をすると前月次月ボタンの関数が動かなくなります。
かといって宣言を外すとjqueryの関数が動かなくなりますが、原因がわかりません

該当するソースコード

calendar.js

    const today = new Date();
    const week = ['', '', '', '', '', '', ''];
    let displayMonth = new Date(today.getFullYear(),today.getMonth());
    window.addEventListener('load', displayCalendar(today));
    var year;
    var month;


    カレンダー表示
    function displayCalendar(date) {
        year = date.getFullYear();
        month = date.getMonth();
        document.getElementById('calendar_main_header_title').innerHTML = `${month+1}月<span>${year}</span>`;

        let calendar = createCalendar(year, month);
        document.getElementById('calendar_main_table').innerHTML = calendar;

    }

    //カレンダー作成
    function createCalendar(year, month){
       // console.log(year);
        let calendar = '<table><tr>';
        for ( let i = 0; i < week.length; i++ ) {
            calendar += '<th>' + week[i] + '</th>';
        }
        calendar += '</tr>';

        let dayCount = 0;
        let startDayOfWeek = new Date(year, month, 1).getDay();
        if ( startDayOfWeek > 0 ) {
            startDayOfWeek -= 1;
        } else {
            startDayOfWeek = 6; 
        };
        let endDate = new Date(year, month + 1, 0).getDate();//月末の日にち
        let weekRow = Math.ceil(( startDayOfWeek + endDate ) / week.length );//1ヵ月の週の数

        for ( let w = 0; w < weekRow; w++ ) {
            //console.log(startDayOfWeek);
            calendar += '<tr>';
            for ( let i = 0; i < week.length; i++ ) {
                if ( w === 0 && i < startDayOfWeek ) {//第1週目且つ、iが週の始まりの曜日番号より小さかったら<td>を空にする
                    calendar += '<td class="background-white"></td>';
                } else if ( dayCount >= endDate ) {//月の最終日よりdayCountが大きくなったら<td>を空にする
                    break;
                } else if ( (startDayOfWeek + dayCount) % 7 === 6  ) {
                    dayCount++;
    //                calendar += '<td class="sun" onClick="dateClick(this)">' + dayCount + '</td>';
                    calendar += '<td class="sun">' + dayCount + '</td>';
                   // console.log(startDayOfWeek);
                } else {
                    dayCount++;
    //                calendar += '<td onClick="dateClick(this)">' + dayCount + '</td>';
                    calendar += '<td>' + dayCount + '</td>';
                }
            }
            calendar += '</tr>';
        }
        calendar += '</table>';
        return calendar;
    };

    //カレンダー前月・次月ボタン
    function prevMonth(){
        displayMonth.setMonth(displayMonth.getMonth()-1);
        displayCalendar(displayMonth);
    }

    function nextMonth(){
        displayMonth.setMonth(displayMonth.getMonth()+1);
        displayCalendar(displayMonth);
        console.log(year);
    }

    $("td").on("click",function(){
        let date = $(this).text();
        let reservationDate = year + "-" +  (month + 1) + "-" +  date;
        console.log( date );

        $.ajax({
            url: "getDate.php",
            type: "POST",
            //dataType: "json",
            data: {"date":reservationDate},
        }).done(function(){
            console.log('success');
        }).fail(function(jqXHR, textStatus, errorThrown, url){
            console.log('error');
            console.log("jqXHR : " + jqXHR.status);
            console.log("textStatus     : " + textStatus);
            console.log("errorThrown    : " + errorThrown.message);
            console.log("URL            : " + url);
        });
    });
calendar.php
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>レッスン・料金のご案内</title>
    <link rel="stylesheet" href="../css/style.css">
    <link href="https://use.fontawesome.com/releases/v5.15.1/css/all.css" rel="stylesheet">
    <script src="../JS/jquery-3.6.0.min.js"></script>
</head>

<!--ヘッダー-->
<?php
  require "header.php";
?>

<!--パンくずリスト-->
<div id="breadcrumb">
  <ul>
    <li><a href="index.php">Home</a></li>
    <li><strong>レッスンについて</strong></li>
  </ul>
</div>

<!--メインコンテンツ-->
<div id="calendar_contents">
    <div id="calendar_header">
        <h1 id="h1">オンライン体験レッスンのご予約</h1>
        <p>こちらは、オンラインでの体験レッスン受講を希望されている方のための予約ページです。教室にて対面での体験レッスンをご希望の方は、以下からご通学予定の教室をお選びください。</p>
        <a href="#">鞍手校</a>-<a href="#">直方校</a>    
    </div>
    <div id="calendar_wrapper">


        <div id="calendar_page1">
            <div id="calendar_page1_header">
                <i class="fas fa-chevron-left" id="prev_month" onclick="prevMonth()"></i>
                <h2 id="calendar_page1_header_title"></h2>
                <i class="fas fa-chevron-right" id="next_month" onclick="nextMonth()"></i>
            </div>
            <div id="calendar_page1_table"></div>
        </div><!--calendar_page1-->

        <div id="calendar_page2">
            <div id="calendar_page2_header">
                <i class="fas fa-chevron-left prev_page" onclick="prevPage()"></i>
                <h2 id="calendar_page2_header_title">2021年5月30日</h2>
                <div><i class="far fa-clock" id="clock_btn"></i></div>
            </div><!--calendar_page2_header-->
            <div id="sub_header">Choose a timeslot</div>
            <div id="calendar_page2_table">
            </div><!--calendar_page2_table-->
        </div><!--calendar_page2-->


    </div><!--calendar_wrapper-->
</div><!--calendar_contents-->
<!--フッター-->

<footer>
  <p>&copy; 2021 escuela sympatica</p>
  <p>
    <a target="_blank" href="#">お問い合わせ</a>&nbsp;|&nbsp;
    <a href="tel:000111222">000-111-222</a>
  </p>
  <br>
  <a href="" class="sns_icon"><i class="fab fa-youtube" aria-hidden="true"></i></a>
  <a href="" class="sns_icon"><i class="fa-facebook fab" aria-hidden="true"></i></a>
  <a href="" class="sns_icon"><i class="fa-instagram fab" aria-hidden="true"></i></a>
</footer>
<script src="../JS/calendar.js"></script>
</body>
</html>


自分で試したこと

素のjsで記述すると解決はできましたが、原因が何なのかわからず気になっております。

0

3Answer

nextMonthが定義されていない」という内容のエラーです。
しかし記載のコードではこれを使用している箇所が無いので、他の部分に原因があるのではないかと思います。

1Like

Comments

  1. ご回答ありがとうございます。htmlのほうにイベントハンドラーを記載しておりました。
    ほかの部分も確認してみます。

Uncaught ReferenceError: nextMonth is not defined のあとにスタックトレースが出ているのではないかと思います。
それをみてどこで発生しているのか、確認してみてはいかがでしょうか?

1Like

Comments

  1. ご回答ありがとうございます。スタックトレースを確認してみましたがなぜそこで発生しているのかがわからず、、、という状況です。

jQueryのセレクター$("td")displayCalendar(date)がHTMLを生成するより先にtdタグを探そうとするが当然見つけられず、現状関数が定義されてないとかイベントも発生しないということになってます。

つまりloadイベントが悪さをしてます。

jQueryを使うのであればスタート関数$(function () {/* 任意のコード */}); にまとめたほうが良いのでは。

1Like

Comments

  1. ご回答ありがとうございます。
    イベントハンドラー記載のhtmlを記載していなかったので追加させていただきました。

    理解力不足でloadの件があまりピンとこないのですが、
    ➀初期読み込み時、カレンダー作成→jquery部分読み込み( $("td")読み込み )
    ②クリックイベントでカレンダー再生成して<td>も新しく生成されたが、再生成された<td>はjqueryで認識されていないということでよろしいでしょうか?

    一応現状としては、$("td")~ajaxの処理後をスタート関数くくっています。
  2. その認識で概ね合っています。
    イベントリスナーを使ってるようですが、これ自体必要であれば、知識についてご自分で何とかなさって下さい。

    イベントリスナーやjQueryのスタート関数についてこだわりが無いのであれば、全て撤去。`script`タグに`defer`属性を付けて実行タイミングはそれらで補います。(無くても`script`タグ位置的に動作はしますがこれについてもご自分で調べ下さい。


    ```javascript
    let displayMonth = new Date(today.getFullYear(),today.getMonth());
    // イベントリスナー削除
    var year;

    // ~中略~

    displayCalendar(today);// 追記
    $("td").on("click",function(){
    ```

    ```html
    <script defer src="../JS/calendar.js">
    ```

    単純に`displayCalendar(today);`→` $("td")`の流れにしてしまえば正常に動作するでしょう。

    またよくコードを確認して欲しいのですが、HTML側の`id`属性`calendar_main_header_title`および`calendar_main_table`が見当たりません。
    これでは`getElementById()`も動作しません。

    `prevPage()`未定義の件やajaxから得るデータ云々に関して本件と関係が無い為、勝手ながら以上とさせて頂きます。
  3. 何度も丁寧に回答いただいてありがとうございます。
    まだ完全に解決はしておりませんが、修正コードを参考に改善することができました。

    >HTML側の`id`属性`calendar_main_header_title`および`calendar_main_table`が見当たりません。
    質問書き込み時に修正前コードを載せてしまっておりご迷惑おかけいたしました。

    今回の件でhtmlパース、jsダウンロード、実行の順序について勉強不足であることがわかりましたので折を見て勉強しよう思います、ありがとうございました。

Your answer might help someone💌