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

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

ただいまの
回答率

87.60%

htmlに埋め込んだjavascritが1度しか実行されない(ajax)

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 368

score 0

前提・実現したいこと

Webで使えるアプリケーションを作るために、サンプルで楽天レシピAPIを使用して 練習しています。
ajax通信を利用して、ページを更新したいです。
下記のコードを実行すると1度目のajax通信は成功していますが、2回目が実行されません(失敗の表記が出てこないため呼び出されていない?)
2度目以降も、同じようにページを更新するにはどの部分の記述を変えればよいでしょうか?

発生している問題

1度目のajax通信は成功し更新されるが、2回目が実行されない。

該当のソースコード

index.jsp : 

最初の画面。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>APIテスト</title>
<script src="${pageContext.request.contextPath}/jquery-3.5.1.js"></script>
</head>
<body>
<h1>APIのテストページです</h1>

<form action = "API" method = "post">
<p>
<input type = "radio" name = "categoryType" value = "small" checked = "checked"> small
<input type = "radio" name = "categoryType" value = "medium" > medium
<input type = "radio" name = "categoryType" value = "large" > large
</p>
<input type = "submit" value = "送信">
</form>

</body>
</html>

API.java : 

サーブレット。categoryTypeをindex.jspから持ってきて、楽天APIからもらえるJsonの中身をそれぞれを返す。

必要な部分だけ記述

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");

        //    カテゴリータイプ    small midium large の中から受け取る
        String categoryType = request.getParameter("categoryType");

        //    外部APIと接続し、jsonからデータを取得
        APICatch a = new APICatch();
        ArrayList<String> NameList = a.getNameList(categoryType);
        ArrayList<String> urlList = a.urlList(categoryType);
        //    セッションスコープにリストデータを保存
        HttpSession session = request.getSession();
        session.setAttribute("nameList", NameList);
        session.setAttribute("urlList", urlList);

        //    結果画面にフォワード
        RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/result.jsp");
        dispatcher.forward(request, response);

    }

}

result.jsp : 

レシピ名にURLを入れて表示する。 ここからajax通信を使ってcategoryTypeを変更した結果を表示させたい。
具体的には、selectで選んだcategoryTypeを上記のAPI.javaに送信し、ページを更新したい。
<script>のdone()の中にあるalert(result)は、resultに何が入っているか確認するために入れました。
このコードは下記サイトを参考にしました。
参考サイト

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>  
    <%@ page import = "java.util.ArrayList"%>
    <%
    ArrayList<String> nameList = (ArrayList<String>) session.getAttribute("nameList");
    ArrayList<String> urlList = (ArrayList<String>) session.getAttribute("urlList");
    %>
<!DOCTYPE html>
<html>
<head>
<script src="${pageContext.request.contextPath}/jquery-3.5.1.js"></script>
<meta charset="UTF-8">
<title>リザルト</title>
</head>
<body>
<script>
    $(function(){  
      //    ボタン押下時の処理
      $('#btn').on('click',function(){

          $.ajax({
              url: "API",
              type: "POST",
              data: {categoryType : $('select').val() }
            }).done(function (result) {
              //     通信成功時のコールバック
                document.write(result);
                alert(result);
            }).fail(function () {
              //     通信失敗時のコールバック
              alert("読み込み失敗");
            }).always(function (result) {
              //     常に実行する処理
            });
          });
    });
</script>

<select>
    <option value ="small">small</option>
    <option value="medium">medium</option>
    <option value="large">large</option>
</select>
 <button id="btn">Ajax</button>

 <% for(int i = 0; i < nameList.size();i++){ %>
<a href = <%= urlList.get(i)%> target=”_blank”><%= nameList.get(i) %></a><br>
<%} %> 

</body>
</html>

試したこと

これを実行し、1度目のajax通信をするとアラートが表示されてページも更新されるのですが、2回からはどの要素を選んで通信を行おうとしても、失敗のアラートすら出てきません。2回目の通信を試みたときにはエラーは出ていません。
![イメージ説明]

補足情報(FW/ツールのバージョンなど)

eclipse Version: 2020-06 (4.16.0)

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

+2

恐らくですが、

  1. ページ読み込み、DOM構築が行われる
  2. 構築されたDOMに存在する#btn要素に対してclickイベントハンドラが設定される
  3. Ajax通信
  4. document.writeによってDOMが全て書き換えられる

という動きになっていますので、4.の段階でclickイベントが設定された#btn要素はDOMから消えています。
なので、document.writeを使用せずに既存のDOMに対してAjax通信後の操作を行うか、document.writeでDOMを書き換えた後に再度clickイベントを設定し直す必要があります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 87.60%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る