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

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

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

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

1回答

1856閲覧

Ajaxでのページ遷移で別の不具合

ndata

総合スコア13

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

2クリップ

投稿2019/03/01 18:41

前提・実現したいこと

jQuery+Express+Node.jsの勉強をしています。
2つのページをAjaxで更新せずに表示切替させたいと思い調べながら見様見真似で以下のコードを用意しました。
EJS1を初期表示させ、確認ダイアログを押すとEJS2が表示されます。
そのままEJS2で何かキーを押すと再びEJS1が表示されます。

ここまでは良いのですが、EJS1に戻ってきた際にEJS2でキー判定に使ったコードが有効になっているままで、
何かキーを押すとEJS1が表示し直されてしまいます。

また、その状態でEJS2を再び表示するとletで宣言した変数countが
既に宣言されている(HTMLが2回読まれている(?))というエラーが出ます。

Ajaxで一度読み込んだコードはページを離れても捨てることはできないのでしょうか?
あるいは、他に解決策があるのでしょうか。

今日、丸一日調べたり試行錯誤しても全く解決の糸口が見つかりませんでした。
助言いただけると幸いです。

該当のソースコード

EJS1

1 let result = confirm('本当に移動しますか?'); 2 if (result) { 3 $.ajax({ 4 type:"GET", 5 url:"Page1", 6 dataType:"html", 7 success: function(data){ 8 $('body').html(data) 9 } 10 }) 11 } 12

EJS2

1 let count = 0; 2 $(document).keydown(() =>{ 3 count++ 4 $.ajax({ 5 type:"GET", 6 url:"helo", 7 dataType:"html", 8 success:function(data){ 9 $('body').html(data); 10 } 11 }) 12 })

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

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

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

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

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

guest

回答1

0

誰も回答がないので、敢えて回答しておきます。

ここまでは良いのですが、EJS1に戻ってきた際にEJS2でキー判定に使ったコードが有効になっているままで、
何かキーを押すとEJS1が表示し直されてしまいます。

これは$(document).keydown()だからだと思います。このイベントはbodyではなく、その上位のdocumentに対してなので、bodyの書き換えでは消えません。なので、EJS1に戻ってもイベントハンドラが有効なままなのです。

また、その状態でEJS2を再び表示するとletで宣言した変数countが
既に宣言されている(HTMLが2回読まれている(?))というエラーが出ます。

一度目の表示で、(恐らく)letでグローバル定義されたcountがあるので、これが残ります。次にまた(恐らく)グローバル定義されたものが読まれても、これは重複してしてしまうのでエラーです。

以上から、

  • documentに対するkeydownイベントのハンドラ解除
  • グローバル変数でないcountの定義

をしたものを書いてみました。Ajaxのままでは実行も出来ないので、setTimeoutにして流し込むHTMLをグローバルの文字列にしています。ハイライトが不自然になってますが、やってることがやってることなので仕方ないと諦めてください。

HTML

1<html> 2<head> 3<script src="jquery-3.3.1.min.js"></script> 4<script> 5 data1 = "\ 6<div><h1>ESJ1</h1></div>\ 7<script>\ 8(function(){\ 9 let result = confirm('本当に移動しますか?');\ 10 if (result) {\ 11 setTimeout(function(){\ 12 $('body').html(data2);\ 13 }, 1);\ 14 }\ 15})();\ 16</" + "script>\ 17 "; 18 data2 = "\ 19<div><h1>ESJ2</h1></div>\ 20<script>\ 21(function(){\ 22 let count = 0;\ 23 $(document).on('keydown', () =>{\ 24 $(document).off('keydown');\ 25 count++;\ 26 setTimeout(function(){\ 27 $('body').html(data1);\ 28 }, 1);\ 29 });\ 30})();\ 31</" + "script>\ 32 "; 33</script> 34</head> 35<body> 36<script> 37$('body').html(data1); 38</script> 39</body> 40</html>

正直なところ、言いたいことはいろいろありますが、どうしてこんなコードになっているのか、理由も分からないので、1つだけ絶対言っていた方がいいことだけ言っておきます。
スクリプトを流し込むのは止めた方がいいです
よく分からないうちは危ないので。


■追記-1
ご指摘があったので、きちんと書いておきます。

今回サンプルで書いたものは、埋め込んだグローバル変数の内容を使っていますが、これはサンプルコードをサーバーなしで動かせるように、本来Ajaxから受け取るはずのデータを書いたものです。なので、この質問者さんの環境でサンプルコードをそのまま使用することはできません。回答そのものは自分で考えて欲しいということもあり、実際の修正内容を載せていなかったのですが、ご指摘で懸念されているように、よく分からずこのまま使用するというのはさらに良くないので、私のサンプルを実際に適用した回答を併記することにしました。

JavaScript

1// EJS1 2(function(){ 3 let result = confirm('本当に移動しますか?'); 4 if (result) { 5 $.ajax({ 6 type:"GET", 7 url:"Page1", 8 dataType:"html", 9 success: function(data){ 10 $('body').html(data); 11 } 12 }); 13 } 14})();

JavaScript

1// EJS2 2(function(){ 3 let count = 0; 4 $(document).on('keydown', () =>{ 5 $(document).off('keydown'); 6 count++; 7 $.ajax({ 8 type:"GET", 9 url:"helo", 10 dataType:"html", 11 success:function(data){ 12 $('body').html(data); 13 } 14 }); 15})();

なお、このコードは、動くようにした(つもり)のものというだけなので、スクリプトの流し込みはそのままの想定になっており、良くないです。ご自分で考えて頂いて、<script></script>要素をAjaxで流し込むのは止めましょう。

投稿2019/03/02 03:23

編集2019/03/02 14:13
wwbQzhMkhhgEmhU

総合スコア343

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

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

bochan2

2019/03/02 10:42

埋め込みは怖いですね 出来れば、後から読む人の為に「ajaxを使え」って目立つように書いていただけないでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問